zoukankan      html  css  js  c++  java
  • 399. Evaluate Division

    问题描述:

    Equations are given in the format A / B = k, where Aand B are variables represented as strings, and k is a real number (floating point number). Given some queries, return the answers. If the answer does not exist, return -1.0.

    Example:
    Given a / b = 2.0, b / c = 3.0. 
    queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? . 
    return [6.0, 0.5, -1.0, 1.0, -1.0 ].

    The input is: vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries , where equations.size() == values.size(), and the values are positive. This represents the equations. Return vector<double>.

    According to the example above:

    equations = [ ["a", "b"], ["b", "c"] ],
    values = [2.0, 3.0],
    queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]. 

    The input is always valid. You may assume that evaluating the queries will result in no division by zero and there is no contradiction.

    解题思路:

    给出已知算式{E1, E2.......En},通过使用已知算式进行运算得到问题算式{Q1, Q2........Qk}的结果,若无法通过当前算式得到结果则返回-1.0

    可以将已知算式 {Ek | k belongs to 1....n}  构建成图,操作数作为顶点,结果作为边的权重。

    由于可能会出现a/b和b/a两种情况,我们使用有向图来表示算式,边从被除数指向除数:

        即 若 算式为 a/b = 2.0 

        可有图  a-----2.0----->b

    我们使用邻接矩阵来表示有向图。

    对于操作数:并不能确定会有什么操作数出现,而我们又需要构建邻接矩阵,所以我们需要一个索引映射(idxMap),将操作符映射到唯一一个索引。

    在得到idxMap后我们可以构建图:

      对每一个算式 a/b = 2.0, 需要更新 graph[a][a] = 1.0, graph[b][b] = 1.0, graph[a][b] = 2.0, graph[b][a] = 1.0/2.0

    得到图后,我们从所求算式的被除数开始进行dfs。

    注意需要visited来保证不出现环(即重复检测)

    代码:

    class Solution {
    public:
        vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
            vector<double> res;
            if(queries.empty()) return res;
            
            //if equations is empty
            if(equations.empty()){
                for(int i = 0; i < queries.size(); i++){
                    res.push_back(-1.0);
                }
                return res;
            }
            //init graph
            unordered_map<string, int> idxMap;
            //init the index mapping
            for(auto e : equations){
                if(idxMap.count(e.first) == 0)  
                    idxMap[e.first] = idxMap.size();
                if(idxMap.count(e.second) == 0)
                    idxMap[e.second] = idxMap.size();
            }
            std::cout<<idxMap.size()<<std::endl;
            //init the graph
            vector<vector<double>> g(idxMap.size(), vector<double>(idxMap.size(), -1.0));
            for(int i = 0; i < equations.size(); i++){
                int dividend = idxMap[equations[i].first];
                int divisor = idxMap[equations[i].second];
                
                g[dividend][divisor] = values[i];
                g[dividend][dividend] = 1.0;
                g[divisor][divisor] = 1.0;
                g[divisor][dividend] = 1.0/values[i];
            }
            
            for(auto q : queries){
                res.push_back(calculateQuery(q, g, idxMap));
            }
            return res;
        }
    private:
        double dfs(vector<vector<double>> &graph, vector<bool> &visited, 
                   int idx, int targetIdx){
            
            for(int i = 0; i < visited.size(); i++){
                if(i == idx) {
                    visited[i] = true;
                    continue;
                }
                if(graph[idx][i] != -1.0){
                    if(i == targetIdx){
                        return graph[idx][targetIdx];
                    }
                    if(!visited[i]){
                        visited[i] == true;
                        double res = dfs(graph, visited, i, targetIdx);
                        if(res != -1){
                            return graph[idx][i] * res;
                        }
                    }
                }
            }
            return -1.0;
        }
        double calculateQuery(pair<string, string> &q, 
                              vector<vector<double>> &graph,
                              unordered_map<string, int> &idxMap){
            int idx, targetIdx;
            if(idxMap.count(q.first) == 0) return -1.0;
            else idx = idxMap[q.first];
            if(idxMap.count(q.second) == 0) return -1.0;
            else targetIdx = idxMap[q.second];
            if(q.first == q.second) return 1.0;
            vector<bool> visited(idxMap.size(), false);
            return dfs(graph, visited, idx, targetIdx);
        }
        
        
    };
  • 相关阅读:
    设置文字内容阴影效果
    android TouchEvent解析(2)
    后台运行 程序
    Intent 大全完整版
    URI URL的区别
    Java中List循环遍历的时候删除当前对象(自己)
    HDU 1005
    XML 导入 Sqlite 遇到的强大工具Navicat
    android eclipse开发环境 自动提示 程序无法响应解决方法
    DOM4J 递归解析xml文件
  • 原文地址:https://www.cnblogs.com/yaoyudadudu/p/10728867.html
Copyright © 2011-2022 走看看