華為筆試題--LISP括號匹配 解析及源碼實現


  在17年校招中3道題目AC卻無緣華為面試,大概是華為和東華互不待見吧!分享一道華為筆試原題,共同進步!

***************************************************************************************************************************************************************************

題目描述:

LISP語言唯一的語法就是括號要匹配。
形如(OP P1 P2 …),括號內元素由單個空格分割。
其中第一個元素OP為操作符,后續元素均為其參數,參數個數取決於操作符類型
注意:參數P1,P2也有可能是另外一個嵌套的(OP P1 P2 …)
其中OP類型為add/sub/mul/div(全小寫),分別代表整數的加減乘除法
其中add/mul參數個數2或以上,sub/div參數個數為2
舉例:
-輸入:(mul 3 -7) 輸出:-21
-輸入:(add1 2 3) 輸出:6
-輸入:(sub (mul 2 4) (div 9 3)) 輸出:5
-輸入:(div 1 0) 輸出:error

題目涉及數字均為整數,可能為負;不考慮32位溢出翻轉
除零錯誤時,輸出"error",除法遇除不盡,取整,即3/2=1

輸入描述:
合法C字符串,字符串長度不超過512;用例保證了無語法錯誤

輸出描述:
合法C字符串,字符包括'0'-'9'及負號'-'或者'error'

示例
輸入 (add 1 2 3) 輸出 6
*********************************************************

  這是數據結構中括號匹配問題的變形。在檢驗括號是否匹配的方法中,可用“期待的急迫程度”這個概念來描述。在算法中設置了一個棧,每讀入一個括號,若是右括號,則或者使置於棧頂的最急迫的期待得以消解,或者是不合法的情況;若是左括號,則作為一個新的更急迫的期待壓入棧中,自然使原有的在棧中的所有未消解的期待的急迫性降了一級。另外,在算法的開始和結束時,棧都應該是空的。
  同樣的道理,針對LISP的括號匹配,我們不僅需要一個符號棧opstack去保存每一個括號里的操作符OP,還需要一個棧strstack去保存括號里的參數P1、P2及符號位。
  從頭到尾對輸入的C字符串進行遍歷,當遇到左括號"("時,將"("壓入strstack中,其后的操作符壓入opstack棧中;當遇到參數P時,通過字符串分割,放入strstack中;當遇到右括號")"時,在strstack棧中依次彈出參數,壓入tmps棧,直到遇到"("為止,那么tmps中為一個不包含子括號參數列表,運算符為opstack的棧頂元素,其中根據操作符和參數可以進行加減乘除運運算,這部分不討論。注意,運算結果需要在壓入strstack棧中作為參數P。
  如下圖所示,以(sub (mul 2 4) (div 9 3))為例,在遇到第一個")"時,strstack中分別為{(,(,2,4},opstack中分別為{sub ,mul},則strstack中依次彈出4,2,(,運算符為opstack的棧頂元素mul,可以得到結果為8,其中運算結果再壓入strstack中作為參數。

  程序輸入輸出,運行結果示意圖:

  源碼分享:

  代碼同步更新於  https://github.com/wylloong/TinyPrograms/blob/master/Coding%20Interviews/LISPGenerateParentheses.cpp

#include <iostream>
#include <algorithm>
#include <string>
#include <stack>
#include <vector>
#include <cstdio>
#include <stdlib.h>
#include <cstring>

using namespace std;

int main()
{
    char chs[512];
    bool error = false;
    gets_s(chs);  
    //gets(chs); //old version
    std::string str(chs);
    std::stack<std::string> opstack;        // operations
    std::stack<std::string> strstack;    // divided strings
    for (int i = 0; i < str.size();)
    {
        if (str[i] == ' ')
        {
            i = i + 1;
            continue;
        }
        if (str[i] == '(')
        {
            strstack.push(std::string("("));
            int spaceIndex = str.find(' ', i);
            std::string tmp = str.substr(i + 1, spaceIndex - i - 1);
            opstack.push(tmp);  // operation
            i = spaceIndex;
        }
        else if (str[i] == ')')
        {
            std::string curOp = opstack.top();
            opstack.pop();
            std::vector<std::string> tmps; // strs temp
            while (strstack.top() != "(")
            {
                tmps.push_back(strstack.top());
                strstack.pop();
            }
            strstack.pop();
            // add
            if (curOp == "add")
            {
                int temp = 0;
                for (int i = 0; i<=tmps.size() - 1; ++i)
                {
                    temp += atoi(tmps[i].c_str());
                }
                strstack.push(to_string(temp));
            }
            // sub
            else if (curOp == "sub")
            {
                int temp = 0;
                if (tmps.size() > 0)
                    temp = atoi(tmps[tmps.size() - 1].c_str());
                for (int i = tmps.size() - 2; i >= 0; --i)
                {
                    temp -= atoi(tmps[i].c_str());
                }
                strstack.push(to_string(temp));
            }
            // mul
            else if (curOp == "mul")
            {
                int temp = 0;
                if (tmps.size() > 0)
                    temp = atoi(tmps[tmps.size() - 1].c_str());
                for (int i = tmps.size() - 2; i >= 0; --i)
                {
                    temp *= atoi(tmps[i].c_str());
                }
                strstack.push(to_string(temp));
            }
            // div
            else if (curOp == "div")
            {
                int temp = 0;
                if (tmps.size() > 0)
                    temp = atoi(tmps[tmps.size() - 1].c_str());
                for (int i = tmps.size() - 2; i >= 0; --i)
                {
                    int data1 = atoi(tmps[i].c_str());
                    if (data1 == 0)
                    {
                        error = true;
                        break;
                    }
                    else
                        temp /= data1;
                }
                if (error)
                    break;
                else
                    strstack.push(to_string(temp));
            }
            ++i;
        }
        else  // substrs
        {
            // get substring by ' ' or ')'
            auto index = str.find(' ', i);
            auto index2= str.find(')', i);
            if (index < index2)
            {
                strstack.push(str.substr(i, index - i));
                i = index;
            }
            else
            {
                strstack.push(str.substr(i, index2 - i));
                i = index2;
            }
        }
    }
    if (error)
        cout << "error";
    else
        cout << atoi(strstack.top().c_str());
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM