原题
https://www.codewars.com/kata/550f22f4d758534c1100025a/train/cpp
题目
Once upon a time, on a way through the old wild west,…
… a man was given directions to go from one point to another. The directions were “NORTH”, “SOUTH”, “WEST”, “EAST”. Clearly “NORTH” and “SOUTH” are opposite, “WEST” and “EAST” too. Going to one direction and coming back the opposite direction is a needless effort. Since this is the wild west, with dreadfull weather and not much water, it’s important to save yourself some energy, otherwise you might die of thirst!
How I crossed the desert the smart way.
The directions given to the man are, for example, the following:
[“NORTH”, “SOUTH”, “SOUTH”, “EAST”, “WEST”, “NORTH”, “WEST”].
[“WEST”]
Other examples:
In [“NORTH”, “SOUTH”, “EAST”, “WEST”], the direction “NORTH” + “SOUTH” is going north and coming back right away. What a waste of time! Better to do nothing.
The path becomes [“EAST”, “WEST”], now “EAST” and “WEST” annihilate each other, therefore, the final result is [] (nil in Clojure).
In [“NORTH”, “EAST”, “WEST”, “SOUTH”, “WEST”, “WEST”], “NORTH” and “SOUTH” are not directly opposite but they become directly opposite after the reduction of “EAST” and “WEST” so the whole path is reducible to [“WEST”, “WEST”].
Task
Write a function dirReduc which will take an array of strings and returns an array of strings with the needless directions removed (W<->E or S<->N side by side).
The Haskell version takes a list of directions with data Direction = North | East | West | South. The Clojure version returns nil when the path is reduced to nothing. The Rust version takes a slice of enum Direction {NORTH, SOUTH, EAST, WEST}.
Example:
dirReduc([“NORTH”, “SOUTH”, “SOUTH”, “EAST”, “WEST”, “NORTH”, “WEST”]) => [“WEST”]
dirReduc([“NORTH”, “SOUTH”, “SOUTH”, “EAST”, “WEST”, “NORTH”]) => []
See more examples in “Example Tests”
Note
Not all paths can be made simpler. The path [“NORTH”, “WEST”, “SOUTH”, “EAST”] is not reducible. “NORTH” and “WEST”, “WEST” and “SOUTH”, “SOUTH” and “EAST” are not directly opposite of each other and can’t become such. Hence the result path is itself : [“NORTH”, “WEST”, “SOUTH”, “EAST”].
分析
该题可以使用括弧匹配的思想去做,利用栈来储存方向,栈顶元素和path字符串方向相反则弹出,最后将栈内元素放到vector中,再将vector反向后,即为最终方向
代码
class DirReduction
{
public:
static std::vector<std::string> dirReduc(std::vector<std::string> &arr);
};
std::vector<std::string> DirReduction::dirReduc(std::vector<std::string> &arr){
std::stack<std::string> s;
/*std::function<const std::string(const std::string&)>*/
auto opposite=[](const std::string& str){
if(str.compare("WEST")==0) return std::string("EAST");
if(str.compare("EAST")==0) return std::string("WEST");
if(str.compare("NORTH")==0) return std::string("SOUTH");
if(str.compare("SOUTH")==0) return std::string("NORTH");
return std::string(" ");
};
s.push(std::string());
for(auto v:arr){
if(s.top()==opposite(v))
s.pop();
else
s.push(v);
}
arr.clear();
while(!s.empty()){
arr.push_back(s.top());s.pop();
}
arr.pop_back();//删除空string
std::reverse(begin(arr),end(arr));
return arr;
}