Directions Reduction -- 5Kyu

原题

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" };

You can immediatly see that going "NORTH" and then "SOUTH" is not reasonable, better stay to the same place! So the task is to give to the man a simplified version of the plan. A better plan in this case is simply:

{ "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}.

  • Examples

dirReduc(["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]) => ["WEST"]
dirReduc(["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH"]) => []
  • 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"].

分析

类似括号匹配问题,使用栈解决匹配问题

参考答案

#include 
#include 
#include 
#include 

using namespace std;

vector dirReduc(vector &arr){
    // 匹配
    const map dir_map
     = {{"NORTH","SOUTH"},{"SOUTH","NORTH"},{"EAST","WEST"},{"WEST","EAST"}};
    stack match; 
    for(auto dir:arr){
        (not match.empty() and match.top() == dir_map.at(dir))?match.pop():match.push(dir);
    }

    // 结果存放到向量
    vector res;
    while(!match.empty()){
        res.push_back(match.top());
        match.pop();
    }

    // 结果反转
    return vector(res.rbegin(),res.rend());
}

说明

使用栈只是理论上最优选择,但是实际上使用向量也是很容易实现的,也避免从栈中取数据与反转结果。

#include 
#include 
#include 

using namespace std;

vector dirReduc(vector &arr){
    // 匹配
    const map dir_map
     = {{"NORTH","SOUTH"},{"SOUTH","NORTH"},{"EAST","WEST"},{"WEST","EAST"}};
    // 结果存放到向量
    vector res;
    for(auto dir:arr){
        (not res.empty() and res.back() == dir_map.at(dir))?res.pop_back():res.push_back(dir);
    }
    return res;
}

其它

你可能感兴趣的:(Directions Reduction -- 5Kyu)