爱编程的卷心菜 2024-09-21 19:55 采纳率: 16.7%
浏览 4

数据结构(c++)课后习题找不出bug

题目描述如下:

img


我的解题思路就是遍历给定的字符串,加密就加上“偏移量(秘钥)”,解密就减掉“偏移量”;秘钥先出队,用完再入队(循环使用)。我同学的编码的思路和我相似,但是他的能过系统的测试用例我的却不能。系统里面不能看见测试用例,只能看见最终输出结果的差异:

img


由于所学有限,实在找不出原因,请大家不吝赐教。
我自己的写法:

string CaesarEncry(const string& input, AQueue<int>& key, int cmd) {
    string result = "";
    for (int i = 0;i < input.length();i++) {
        char c = input[i];
        int shift = key.dequeue();
        if (cmd == 1) {
            cmd = 1;
        } else {
            cmd = -1;
        }
        c = c + (cmd * shift);
        result += c;
        key.enqueue(shift);
    }
    return result;
}

我同学的写法:

string CaesarEncry2(const string& input, AQueue<int>& key, int cmd) {
    string result="";
    for (size_t i = 0; i < input.length(); ++i) {
        char currentChar = input[i];
        int shift = key.frontValue(); // Get the current shift from the queue
        key.enqueue(key.dequeue()); // Rotate the key

        if (cmd == 1) { // Encrypt
            result += static_cast<char>(currentChar + shift);
        } else if (cmd == 2) { // Decrypt
            result += static_cast<char>(currentChar - shift);
        }
    }
    return result;
}

以下题目所给的参考代码:

#include<string>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <bitset>

using namespace std;

using std::cout;
using std::endl;
using std::string;
using std::ostream;

const int defaultSize = 10; // Default size


// Assert: If "val" is false, print a message and terminate
// the program
void Assert(bool val, string s) {
    if (!val) { // Assertion failed -- close the program
        cout << "Assertion Failed: " << s << endl;
        exit(-1);
    }
}

// Abstract queue class
template <typename E> class Queue {
private:
    void operator =(const Queue&) {}     // Protect assignment
    Queue(const Queue&) {}         // Protect copy constructor

public:
    Queue() {}          // Default
    virtual ~Queue() {} // Base destructor

    // Reinitialize the queue.  The user is responsible for
    // reclaiming the storage used by the queue elements.
    virtual void clear() = 0;

    // Place an element at the rear of the queue.
    // it: The element being enqueued.
    virtual void enqueue(const E&) = 0;

    // Remove and return element at the front of the queue.
    // Return: The element at the front of the queue.
    virtual E dequeue() = 0;

    // Return: A copy of the front element.
    virtual const E& frontValue() const = 0;

    // Return: The number of elements in the queue.
    virtual int length() const = 0;
};


// This is the declaration for AStack.
// Array-based queue implementation
template <typename E> class AQueue : public Queue<E> {
private:
    int maxSize;               // Maximum size of queue
    int front;                 // Index of front element
    int rear;                  // Index of rear element
    E* listArray;           // Array holding queue elements

public:
    AQueue(int size = defaultSize) {  // Constructor
        // Make list array one position larger for empty slot
        maxSize = size + 1;
        rear = 0;  front = 1;
        listArray = new E[maxSize];
    }

    ~AQueue() { delete[] listArray; } // Destructor

    void clear() { rear = 0; front = 1; } // Reinitialize

    void enqueue(const E& it) {     // Put "it" in queue
        rear = (rear + 1) % maxSize;
        listArray[rear] = it;

    }

    E dequeue() { // Take element out
        E it = listArray[front];
        front = (front + 1) % maxSize;
        return it;
    }

    const E& frontValue() const {  // Get front value
        Assert(length() != 0, "Queue is empty");
        return listArray[front];
    }

    virtual int length() const         // Return length
    {
        return ((rear + maxSize) - front + 1) % maxSize;
    }
};

// 补全这个函数
string CaesarEncry(const string& input, AQueue<int>& key, int cmd) {
    string result = "";

    return result;
}

int main() {

    AQueue<int> qkey(16);
    int cmd = 0, num;
    string strkey, str;
    string item;

    //inputs
    getline(cin, strkey);
    getline(cin, str);
    cin >> cmd;

    stringstream str_num(strkey);

    while (getline(str_num, item, ' ')) {
        num = stoi(item);
        qkey.enqueue(num);
    }
    return 0;
}
  • 写回答

2条回答 默认 最新

  • 清水白石008 2024-09-22 17:04
    关注
    🕒下午好,题主!目前:🟢[在线]
    📢参考GPT-4o mini 模型、由清水白石008整理提供!
    📣今日金句:“成功是由不断追求卓越的精神所驱动的。”** — 史蒂夫·乔布斯
    

    你的代码和你同学的代码在实现凯撒加密时有一些不同之处。以下是对你代码的详细分析和改进建议:

    1. 你的代码分析

    你的代码在处理加密和解密时有一些问题:

    • cmd 的值在每次循环中都被重新设置为 1-1,这会导致加密和解密逻辑不正确。
    • key.dequeue() 会移除队列中的元素,这可能会导致队列中的元素顺序发生变化。

    2. 改进后的代码

    以下是改进后的代码,确保加密和解密逻辑正确,并且队列中的元素顺序保持不变:

    #include <iostream>
    #include <string>
    #include <sstream>
    #include <cstdlib>
    
    using namespace std;
    
    const int defaultSize = 10; // Default size
    
    // Assert: If "val" is false, print a message and terminate the program
    void Assert(bool val, string s) {
        if (!val) { // Assertion failed -- close the program
            cout << "Assertion Failed: " << s << endl;
            exit(-1);
        }
    }
    
    // Abstract queue class
    template <typename E> class Queue {
    private:
        void operator =(const Queue&) {}     // Protect assignment
        Queue(const Queue&) {}         // Protect copy constructor
    
    public:
        Queue() {}          // Default
        virtual ~Queue() {} // Base destructor
    
        // Reinitialize the queue.  The user is responsible for reclaiming the storage used by the queue elements.
        virtual void clear() = 0;
    
        // Place an element at the rear of the queue.
        // it: The element being enqueued.
        virtual void enqueue(const E&) = 0;
    
        // Remove and return element at the front of the queue.
        // Return: The element at the front of the queue.
        virtual E dequeue() = 0;
    
        // Return: A copy of the front element.
        virtual const E& frontValue() const = 0;
    
        // Return: The number of elements in the queue.
        virtual int length() const = 0;
    };
    
    // Array-based queue implementation
    template <typename E> class AQueue : public Queue<E> {
    private:
        int maxSize;               // Maximum size of queue
        int front;                 // Index of front element
        int rear;                  // Index of rear element
        E* listArray;           // Array holding queue elements
    
    public:
        AQueue(int size = defaultSize) {  // Constructor
            // Make list array one position larger for empty slot
            maxSize = size + 1;
            rear = 0;  front = 1;
            listArray = new E[maxSize];
        }
    
        ~AQueue() { delete[] listArray; } // Destructor
    
        void clear() { rear = 0; front = 1; } // Reinitialize
    
        void enqueue(const E& it) {     // Put "it" in queue
            rear = (rear + 1) % maxSize;
            listArray[rear] = it;
        }
    
        E dequeue() { // Take element out
            E it = listArray[front];
            front = (front + 1) % maxSize;
            return it;
        }
    
        const E& frontValue() const {  // Get front value
            Assert(length() != 0, "Queue is empty");
            return listArray[front];
        }
    
        virtual int length() const { // Return length
            return ((rear + maxSize) - front + 1) % maxSize;
        }
    };
    
    // 补全这个函数
    string CaesarEncry(const string& input, AQueue<int>& key, int cmd) {
        string result = "";
        for (int i = 0; i < input.length(); i++) {
            char c = input[i];
            int shift = key.frontValue(); // 获取当前的移位值
            key.enqueue(key.dequeue()); // 旋转队列
    
            if (cmd == 1) { // 加密
                c = c + shift;
            } else if (cmd == 2) { // 解密
                c = c - shift;
            }
            result += c;
        }
        return result;
    }
    
    int main() {
        AQueue<int> qkey(16);
        int cmd = 0, num;
        string strkey, str;
        string item;
    
        // 输入
        getline(cin, strkey);
        getline(cin, str);
        cin >> cmd;
    
        stringstream str_num(strkey);
    
        while (getline(str_num, item, ' ')) {
            num = stoi(item);
            qkey.enqueue(num);
        }
    
        string result = CaesarEncry(str, qkey, cmd);
        cout << "结果: " << result << endl;
    
        return 0;
    }
    

    解释代码

    1. 队列实现

      • AQueue 类实现了一个基于数组的队列,用于存储移位值。
    2. 凯撒加密函数

      • CaesarEncry 函数根据 cmd 参数决定是加密还是解密。
      • 使用 key.frontValue() 获取当前的移位值,并使用 key.enqueue(key.dequeue()) 旋转队列,确保队列中的元素顺序保持不变。
    3. 主函数

      • 从输入中读取移位值和要加密/解密的字符串。
      • 调用 CaesarEncry 函数进行加密或解密,并输出结果。

    希望这些改进能帮助你解决问题。如果你有任何疑问或需要进一步的帮助,请随时告诉我!

    评论

报告相同问题?

问题事件

  • 创建了问题 9月21日

悬赏问题

  • ¥15 ArcGIS批量裁剪
  • ¥15 labview程序设计
  • ¥15 为什么在配置Linux系统的时候执行脚本总是出现E: Failed to fetch http:L/cn.archive.ubuntu.com
  • ¥15 Cloudreve保存用户组存储空间大小时报错
  • ¥15 伪标签为什么不能作为弱监督语义分割的结果?
  • ¥15 编一个判断一个区间范围内的数字的个位数的立方和是否等于其本身的程序在输入第1组数据后卡住了(语言-c语言)
  • ¥15 游戏盾如何溯源服务器真实ip?
  • ¥15 Mac版Fiddler Everywhere4.0.1提示强制更新
  • ¥15 android 集成sentry上报时报错。
  • ¥50 win10链接MySQL