Извините, если это спросили прежде, но я задаюсь вопросом что использование std::vector::front()
.
Есть ли причина использовать, например. myvector.front()
вместо myvector[0]
или myvector.at(0)
?
Посмотрите на другие алгоритмы поиска путей (например, Breath-First, Depth-First, Minimax, Negmax и т.д.) и взвесьте положительные и отрицательные результаты для вашего сценария.
Boost также имеет A-звездообразную реализацию . Попробуйте выполнить эти инструкции , чтобы построить повышение на iPhone, но это может не сработать для вас: это не «полный порт» повышения и он может ошибиться.
Ниже приведены Алгоритмы в двух словах (Java, а не C++, но, возможно, вы хотите его перенести):
public Solution search( INode initial, INode goal ) {
// Start from the initial state
INodeSet open = StateStorageFactory.create( StateStorageFactory.TREE );
INode copy = initial.copy();
scoringFunction.score( copy );
open.insert( copy );
// Use Hashtable to store states we have already visited.
INodeSet closed = StateStorageFactory.create( StateStorageFactory. HASH );
while( !open.isEmpty() ) {
// Remove node with smallest evaluation function and mark closed.
INode n = open.remove();
closed.insert( n );
// Return if goal state reached.
if( n.equals( goal ) ) { return new Solution( initial, n ); }
// Compute successor moves and update OPEN/CLOSED lists.
DepthTransition trans = (DepthTransition)n.storedData();
int depth = 1;
if( trans ! = null ) { depth = trans.depth + 1; }
DoubleLinkedList<IMove> moves = n.validMoves();
for( Iterator<IMove> it = moves.iterator(); it.hasNext(); ) {
IMove move = it.next();
// Make move and score the new board state.
INode successor = n.copy();
move.execute( successor );
// Record previous move for solution trace and compute
// evaluation function to see if we have improved upon
// a state already closed
successor.storedData( new DepthTransition( move, n, depth ) );
scoringFunction.score( successor );
// If already visited, see if we are revisiting with lower
// cost. If not, just continue; otherwise, pull out of closed
// and process
INode past = closed.contains( successor );
if( past ! = null ) {
if( successor.score() >= past.score() ) {
continue;
}
// we revisit with our lower cost.
closed.remove( past );
}
// place into open.
open.insert( successor );
}
}
// No solution.
return new Solution( initial, goal, false );
}
-121--2463722- Некоторые общие алгоритмы, которые также работают в списках, используют его.
Это пример общего принципа: если вы предоставляете средства доступа для всей семантики , которую вы поддерживаете, а не только реализации , которую вы поддерживаете, проще написать обобщенно и, следовательно, проще повторно использовать код.
Если тип мивектора меняется на другой тип данных, который не индексируется, например, на список, вам не придется менять код, который обращается к передней части контейнера.
Это обеспечивает что-то называемое статическим полиморфизмом.
Допустим, я написал алгоритм, используя класс очереди. Он имеет фронт () функцию, чтобы получить следующий элемент очереди, и функцию Enqueue (), чтобы добавить в конец очереди. Теперь скажем, я обнаружил, что этот класс очереди написан плохо и очень медленно, и я бы предпочел бы использовать STD :: Vector, который намного быстрее (я знаю, что есть std :: queue, это просто пример). Если единственный способ получить первый элемент STD :: Vector был с V [0], мне придется пройти свой код и заменить все мои звонки перед фронтами () с [0]. Но путем внедрения фронта (), STD :: Vector теперь может быть заменой для моего класса очереди. Единственный код, который я должен изменить, это тип контейнера в моем алгоритме.