来自终端的字符串流可变长度的输入,什么是最佳实现方式

问题描述 投票:0回答:1

我正在做一个分配,要求我们用值填充AVL树。

代码需要从终端开始一行并执行对树的添加和删除。然后最终按顺序打印AVL树。

来自终端的字符串看起来像这样

A3 A5 A6 D5 D6 print 

字符串可以是任意长度的1-100输入长。

我的问题是实现终端读取器功能的最佳方法是什么,该功能可以有效地记录和输入值,甚至初始化输入,删除和打印功能?

我熟悉字符串流和sstream库,但是正在努力找到解决该问题的好方法。

我正在设想的函数的某些伪代码看起来像这样。

void stringReader(string sentence){
    string word;
    stringstream instring(input);

    instring >> word;//word should be a single input ie: "A3" or "D6" 
                     //in the 0th position of the string stream.

    if (word == "print"){
        printAVL(node* treeroot);
        return; 
    }else{
        if(statement to determine if A or D){
              //perform deletion or addition;
        }
    }
    input.removeFirstWord()//some magic function I am yet to find that removes the first input 
                           //and allows me to do this recursively.
    stringReader(input);

}

int main(){
    string input; 
    getline(cin, input);//the raw input line from terminal ie;"A3 A5 A6 D5 D6 print"
    stringReader(input);
}

我不是100%致力于递归方法,也不会对使用sstream库有任何想法或方法心存感激。

编辑-使用while循环并将字符串附加到向量是我正在研究的另一个想法。

感谢您的帮助

PS-任务是判断我们编写AVL树程序的能力,未标记输入的处理。我只想使用一种不错的方法,并有机会进一步发展自己的技能。

c++ user-input stringstream
1个回答
0
投票

您不需要递归函数,也不需要魔术“ removeFirstWord”函数。

如果在std::istringstream中有数据,并使用>>运算符提取,则数据已经“消失”,您将不再读取它。 stream的内部机制将推进一些内部指针。 (这是一个非常简化的解释)。

解决方案是,通过一个简单的while循环提取std::istringstream中的所有单词。提取语句instring >> word返回对原始std::istringstream的引用,在本例中为“ instring”。并且boolstreams运算符有一个替代值,它指示流的fail位是否已设置。并且,当流完全“清空”(EOF)时,也将设置此值。

因此,使用命令

while (instring >> word) {

您将读取“ instring”中的所有单词。

然后您可以检查有效命令并执行必要的操作。

您可以在下面的示例中看到它。请注意:我没有实现AVL树。我使用std::set进行了模拟。您需要自己实现AVL树。

示例(许多可能的解决方案之一:

#include <iostream>
#include <string>
#include <set>
#include <sstream>

// A Pseudo AVL. It is a std::set and a Red Black tree
struct PretendToBeAnAVLtree {

    // Data container
    std::set<int> data{};

    // Add function
    void addValue(int value) {
        auto result = data.insert(value);
        if (!result.second) std::cerr << "\n*** Error Add: Value " << value << " is already in tree\n";
    };
    // Delete function
    void deleteValue(int value) {
        auto it = data.find(value);
        if (it == data.end())
            std::cerr << "\n*** Error Delete: Value " << value << " is not in tree\n";
        else
            data.erase(it);
    }
    // Print function
    void print() {
        for (const int i : data) std::cout << i << " ";
        std::cout << "\n\n";
    }
};

// Replace PretendToBeAnAVLtree with your implementation of a real AVL tree
using AVL = PretendToBeAnAVLtree;

// Read some string and execute the commands in the input string
void processInputData(const std::string& input, AVL& avl) {

    // Some debug output
    std::cout << "\nInput data: " << input << "\n";

    // Put the input string into an istringstream for easier word extraction
    std::istringstream instring(input);

    // Now read all words from the istringstream and and consume them
    std::string word{};
    while (instring >> word) {

        // Depending on the command in the word
        // Check for print command
        if (word == "print") {
            avl.print(); 
        } // Check for add command
        else if (word[0] == 'A') {
            try { 
                // Convert string starting at position 1 of the word to an integer
                int value = std::stoi(word.substr(1));
                // Add the value to the tree
                avl.addValue(value); }
            // In case of conversion error 
            catch (...) { std::cerr << "\n*** Error: Invalid add command '" << word << "' in input data\n"; }
        } // Check for Delete
        else if (word[0] == 'D') {
            try {
                // Convert string starting at position 1 of the word to an integer
                int value = std::stoi(word.substr(1));
                // Delete the value from the tree
                avl.deleteValue(value);
            }
            // In case of conversion error 
            catch (...) { std::cerr << "\n*** Error: Invalid delete command '" << word << "' in input data\n"; }
        }
        else {
            // In case of a totaly unknown command
            std::cerr << "\n*** Error: Invalid command '" << word << "' in input data\n";
        }
    }
}

// Driver code
int main() {

    // The AVL
    AVL avl;

    // Some test commands
    processInputData("A3 A5 A6 D5 D6 print", avl);
    processInputData("A1 A2 A4 A5 print A6 A7 A8 A9 print", avl);
    processInputData("A3 A100 print", avl);
    processInputData("D3 D4 D555 print", avl);
    processInputData("A200 X999 A300 print", avl);

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.