[Редактирование] Там является другим решением, не упомянутым все же, и это, кажется, превосходит по характеристикам другие данных до сих пор в большинстве случаев.
Использование string.translate, чтобы заменить все допустимые символы в строке и видеть, имеем ли мы какие-либо недопустимые в запасе. Это довольно быстро, поскольку это использует базовую функцию C, чтобы сделать работу с очень небольшим количеством включенного байт-кода Python.
, Очевидно, производительность не, все - идущий для большинства читаемых решений является, вероятно, лучшим подходом если не в производительности критический путь выполнения кода, но только видеть, как решения складывают, вот сравнение производительности всех методов, предложенных до сих пор. check_trans является тем с помощью string.translate метода.
Тестовый код:
import string, re, timeit
pat = re.compile('[\w-]* результаты в моей системе:
Test test_empty (length = 0):
check_re_inverse : 0.042
check_re_match : 0.030
check_set_all : 0.027
check_set_diff : 0.029
check_set_subset : 0.029
check_trans : 0.014
Test test_long_almost_valid (length = 5941):
check_re_inverse : 2.690
check_re_match : 3.037
check_set_all : 18.860
check_set_diff : 2.905
check_set_subset : 2.903
check_trans : 0.182
Test test_long_invalid (length = 594):
check_re_inverse : 0.017
check_re_match : 0.015
check_set_all : 0.044
check_set_diff : 0.311
check_set_subset : 0.308
check_trans : 0.034
Test test_long_valid (length = 4356):
check_re_inverse : 1.890
check_re_match : 1.010
check_set_all : 14.411
check_set_diff : 2.101
check_set_subset : 2.333
check_trans : 0.140
Test test_short_invalid (length = 6):
check_re_inverse : 0.017
check_re_match : 0.019
check_set_all : 0.044
check_set_diff : 0.032
check_set_subset : 0.037
check_trans : 0.015
Test test_short_valid (length = 18):
check_re_inverse : 0.125
check_re_match : 0.066
check_set_all : 0.104
check_set_diff : 0.051
check_set_subset : 0.046
check_trans : 0.017
переводить подход кажется лучшим в большинстве случаев, существенно так с долгими допустимыми строками, но сбит regexes в test_long_invalid (По-видимому, потому что regex может сразу прыгнуть с парашютом, но перевести, всегда должен сканировать целую строку). Подходы набора обычно хуже, избивая regexes только для случая пустой строки.
Используя все (x в allowed_set для x в s) работает хорошо, если это прыгает с парашютом рано, но может быть плохо, если это должно выполнить итерации через каждый символ. isSubSet и разность множеств сопоставимы, и последовательно пропорциональны длине строки независимо от данных.
существует подобное различие между regex методами, соответствующими всем допустимым символам и ищущими недопустимые символы. Соответствие работает немного лучше при проверке на долгую, но полностью допустимую строку, но хуже для недопустимых символов около конца строки.
)
pat_inv = re.compile ('[^\w-]')
allowed_chars=string.ascii_letters + string.digits + '_-'
allowed_set = set(allowed_chars)
trans_table = string.maketrans('','')
def check_set_diff(s):
return not set(s) - allowed_set
def check_set_all(s):
return all(x in allowed_set for x in s)
def check_set_subset(s):
return set(s).issubset(allowed_set)
def check_re_match(s):
return pat.match(s)
def check_re_inverse(s): # Search for non-matching character.
return not pat_inv.search(s)
def check_trans(s):
return not s.translate(trans_table,allowed_chars)
test_long_almost_valid='a_very_long_string_that_is_mostly_valid_except_for_last_char'*99 + '!'
test_long_valid='a_very_long_string_that_is_completely_valid_' * 99
test_short_valid='short_valid_string'
test_short_invalid='/$%$%&'
test_long_invalid='/$%$%&' * 99
test_empty=''
def main():
funcs = sorted(f for f in globals() if f.startswith('check_'))
tests = sorted(f for f in globals() if f.startswith('test_'))
for test in tests:
print "Test %-15s (length = %d):" % (test, len(globals()[test]))
for func in funcs:
print " %-20s : %.3f" % (func,
timeit.Timer('%s(%s)' % (func, test), 'from __main__ import pat,allowed_set,%s' % ','.join(funcs+tests)).timeit(10000))
print
if __name__=='__main__': main()
результаты в моей системе:
Test test_empty (length = 0):
check_re_inverse : 0.042
check_re_match : 0.030
check_set_all : 0.027
check_set_diff : 0.029
check_set_subset : 0.029
check_trans : 0.014
Test test_long_almost_valid (length = 5941):
check_re_inverse : 2.690
check_re_match : 3.037
check_set_all : 18.860
check_set_diff : 2.905
check_set_subset : 2.903
check_trans : 0.182
Test test_long_invalid (length = 594):
check_re_inverse : 0.017
check_re_match : 0.015
check_set_all : 0.044
check_set_diff : 0.311
check_set_subset : 0.308
check_trans : 0.034
Test test_long_valid (length = 4356):
check_re_inverse : 1.890
check_re_match : 1.010
check_set_all : 14.411
check_set_diff : 2.101
check_set_subset : 2.333
check_trans : 0.140
Test test_short_invalid (length = 6):
check_re_inverse : 0.017
check_re_match : 0.019
check_set_all : 0.044
check_set_diff : 0.032
check_set_subset : 0.037
check_trans : 0.015
Test test_short_valid (length = 18):
check_re_inverse : 0.125
check_re_match : 0.066
check_set_all : 0.104
check_set_diff : 0.051
check_set_subset : 0.046
check_trans : 0.017
переводить подход кажется лучшим в большинстве случаев, существенно так с долгими допустимыми строками, но сбит regexes в test_long_invalid (По-видимому, потому что regex может сразу прыгнуть с парашютом, но перевести, всегда должен сканировать целую строку). Подходы набора обычно хуже, избивая regexes только для случая пустой строки.
Используя все (x в allowed_set для x в s) работает хорошо, если это прыгает с парашютом рано, но может быть плохо, если это должно выполнить итерации через каждый символ. isSubSet и разность множеств сопоставимы, и последовательно пропорциональны длине строки независимо от данных.
существует подобное различие между regex методами, соответствующими всем допустимым символам и ищущими недопустимые символы. Соответствие работает немного лучше при проверке на долгую, но полностью допустимую строку, но хуже для недопустимых символов около конца строки.
Lat_to_Travel = CurLat - TargetLat
Long_to_Travel = CurLong - TargetLong
Time_to_Travel = ETA - now
Если расстояния относительно малы, вероятно нормально предположить линейную прогрессию по этим трем измерениям (*). Затем вам нужно выбрать количество промежуточных позиций для отображения, скажем 10, и соответственно рассчитать каждую промежуточную точку
NbOfIntermediates = 10 // for example
Lat_at_Intermediate(n) = CurLat + (1/NbOfIntermediates * Lat_to_travel)
Long_at_Intermediate(n) = CurLong + (1/NbOfIntermediates * Long_to_travel)
Time_at_Intermediate(n) = now + (1/NbOfIntermediates * Time_to_travel)
Самым сложным во всем этом является поддержание единиц в порядке.
(*) Несколько соображения относительно того, допустимо ли предположить линейную прогрессию ...
Очевидно, что особенности реальности физических элементов (морские течения, ветер, видимость ...) могут иметь большее значение в этом материи, чем геопространственная математика.
Предполагая, что транспортное средство движется с постоянной скоростью по прямой линии, [ обычно ] нормально принимать линейность в измерении широты [технически говоря, земля не является точно сфера, это не совсем так, но чертовски близко]. Однако на больших расстояниях, которые включают относительно большое изменение широты, угловая прогрессия по долготе не является линейной. Причина в том, что по мере удаления от экватора степень долготы, выраженная в линейных милях (или километрах ...), уменьшается. Следующая таблица должна дать приблизительное представление об этом эффекте для местоположений на разных широтах:
Latitude Length of a Degree Approximate examples (of longitude) in nautical miles 0 60 Kuala Lumpur, Bogota, Nairobi 20 56.5 Mexico city, Mecca, Mumbai, Rio de Janeiro 45 42.5 Geneva, Boston, Seattle, Beijing, Wellington (NZ) 60 30 Oslo, Stockholm, Anchorage AK, St Petersburg Russia
См. Этот удобный онлайн-калькулятор , чтобы вычислить его для конкретной широты.
[ в общем ] нормально допускать линейность в измерении Широты [ну технически Земля не совсем сфера, это не совсем верно, но чертовски близко]. Однако на больших расстояниях, которые включают относительно большое изменение широты, угловая прогрессия по долготе не является линейной. Причина этого в том, что по мере удаления от экватора степень долготы, выраженная в линейных милях (или километрах ...), уменьшается. Следующая таблица должна дать приблизительное представление об этом эффекте для местоположений на разных широтах:
Latitude Length of a Degree Approximate examples (of longitude) in nautical miles 0 60 Kuala Lumpur, Bogota, Nairobi 20 56.5 Mexico city, Mecca, Mumbai, Rio de Janeiro 45 42.5 Geneva, Boston, Seattle, Beijing, Wellington (NZ) 60 30 Oslo, Stockholm, Anchorage AK, St Petersburg Russia
См. Этот удобный онлайн-калькулятор , чтобы вычислить его для конкретной широты.
[ в целом ] нормально допускать линейность в измерении Широты [ну технически Земля не совсем сфера, это не совсем верно, но чертовски близко]. Однако на больших расстояниях, которые включают относительно большое изменение широты, угловая прогрессия по долготе не является линейной. Причина этого в том, что по мере удаления от экватора степень долготы, выраженная в линейных милях (или километрах ...), уменьшается. Следующая таблица должна дать приблизительное представление об этом эффекте для местоположений на разных широтах:
Latitude Length of a Degree Approximate examples (of longitude) in nautical miles 0 60 Kuala Lumpur, Bogota, Nairobi 20 56.5 Mexico city, Mecca, Mumbai, Rio de Janeiro 45 42.5 Geneva, Boston, Seattle, Beijing, Wellington (NZ) 60 30 Oslo, Stockholm, Anchorage AK, St Petersburg Russia
См. Этот удобный онлайн-калькулятор , чтобы вычислить это для конкретной широты.
на больших расстояниях, которые включают относительно большое изменение широты, угловая прогрессия по долготе не является линейной. Причина этого в том, что по мере удаления от экватора степень долготы, выраженная в линейных милях (или километрах ...), уменьшается. Следующая таблица должна дать приблизительное представление об этом эффекте для местоположений на разных широтах:
Latitude Length of a Degree Approximate examples (of longitude) in nautical miles 0 60 Kuala Lumpur, Bogota, Nairobi 20 56.5 Mexico city, Mecca, Mumbai, Rio de Janeiro 45 42.5 Geneva, Boston, Seattle, Beijing, Wellington (NZ) 60 30 Oslo, Stockholm, Anchorage AK, St Petersburg Russia
См. Этот удобный онлайн-калькулятор , чтобы вычислить это для конкретной широты.
на больших расстояниях, которые включают относительно большое изменение широты, угловая прогрессия по долготе не является линейной. Причина этого в том, что по мере удаления от экватора степень долготы, выраженная в линейных милях (или километрах ...), уменьшается. Следующая таблица должна дать приблизительное представление об этом эффекте для местоположений на разных широтах:
Latitude Length of a Degree Approximate examples (of longitude) in nautical miles 0 60 Kuala Lumpur, Bogota, Nairobi 20 56.5 Mexico city, Mecca, Mumbai, Rio de Janeiro 45 42.5 Geneva, Boston, Seattle, Beijing, Wellington (NZ) 60 30 Oslo, Stockholm, Anchorage AK, St Petersburg Russia
См. Этот удобный онлайн-калькулятор , чтобы вычислить его для конкретной широты.
Другой способ получить представление об этом - увидеть, что путешествие на восток (или запад) на широте Джексонвилля, Флорида, или Сан-Диего, Калифорния, занимает 52 мили, чтобы преодолеть градус долготы; на широте Монреаля или Сиэтла это займет всего 40 миль.
Вы хотите использовать Slerp или сферическую линейную интерполяцию.
Преобразуйте широту и долготу в единичный 3-вектор:
p=(x,y,z)=(cos(lon)*cos(lat), sin(lon)*cos(lat), sin(lat))
Затем, "Slerp "дает вам интерполяцию с постоянной скоростью по поверхности единичной сферы:
theta= angle between 3-vectors p0 and p1 (e.g., cos(theta)= p0.p1)
Slerp(p0,p1,t)= ( p0*sin((1-t)*theta) + p1*sin(t*theta) ) / sin(theta)
Обратите внимание, что если тета очень близка к 0 или 180 градусам, эта формула может быть численно нестабильной. В случае малого угла вы можете вернуться к линейной интерполяции; в случае 180 градусов ваш путь действительно неоднозначен.