在函数中编码两个向量

时间:2014-07-19 20:17:28

标签: c++ c++11 vector

嘿,我正在编写一个需要两个std::vector<std::string>并返回第三个std::vector<std::string>的函数。

该函数将两个向量编码在一起并创建第三个向量。

我目前正在对此进行调试,以了解它无法正常工作的原因,并且我不断获得:vector subscript out of range。据我所知,它在这条线上崩溃了:

if (file2[i].size() < file1[i].size())

我可以使用size()来获取i元素的大小吗?

std::vector<std::string> Encode(std::vector<std::string> &file1,
                                std::vector<std::string> &file2)
{
    std::vector<std::string> file3;
    std::string temp;

    for (unsigned int i = 0; i < file1.size(); i++) {
        for (unsigned int x = 0; x < file1[i].size(); x++) {
            if (file2[i].size() < file1[i].size()) {
                for (unsigned int t = 0; t < file2[i].size(); t++) {
                    file3[i][x] = (int)file1[i][x] + (int)file2[i][t];
                }
            } else if (file2[i].size() > file1[i].size()) {
                file3[i][x] = (int)file1[i][x] + (int)file2[i][x];
            }

            if (file3[i][x] > 126) {
                file3[i][x] = file3[i][x] % 127;
            } else {
                file3[i][x] = file3[i][x] + 32;
            }
        }
    }
    return file3;
}

知道这里发生了什么吗?

3 个答案:

答案 0 :(得分:0)

我非常倾向于通过保理来简化。在最低层是一个combine函数,用于将两个char合并为一个:

char combine(char a, char b)
{
    char result = a+b;
    if (result > 126)
        return result % 127;
    return result+32;
}

下一个级别是迭代两个可能不同大小的字符串中的每个字母。该算法通过较短的字符串“循环”来处理不同长度的字符串。

std::string mix(const std::string &first, const std::string &second)
{
    unsigned len1 = first.length();
    unsigned len2 = second.length();
    if (len1 < len2)
        return mix(second, first);
    std::string result;
    // if the strings are of different lengths, first is now the longer
    unsigned j=0;
    for (unsigned i=0; i < len1; ++i, ++j) {
        if (j >= len2)
            j = 0;
        result.push_back(combine(first[i], second[j]));
    }
    return result;
}

最后,vector string的组合更加简单:

std::vector<std::string> Encode(const std::vector<std::string> &file1,
                                const std::vector<std::string> &file2)
{
    std::vector<std::string> file3;

    assert(file1.size() == file2.size());
    for (unsigned int i = 0; i < file1.size(); i++) {
        file3.push_back(mix(file1[i], file2[i]));
    }
    return file3;
}

请注意,代码当前使用assert来确保两个vector的长度相同,但这可能是一个人为约束。真正的代码应该确保它们是相同的长度或做其他事情来处理这种情况。由于我们不清楚你的功能是做什么的,我已经让你决定如何处理它,但是以assert作为占位符来提醒你确实需要解决它。

最后,一些使用C ++ 11的驱动程序代码:

int main()
{
    std::vector<std::string> english{"one", "two", "three", "four"};
    std::vector<std::string> spanish{"uno", "dos", "tres", "cuatro"}; 

    auto result = Encode(english, spanish);

    std::copy(result.begin(), result.end(), 
              std::ostream_iterator<std::string>(std::cout, " "));
}

另请注意,我已使用push_back附加到字符串的末尾,并为传递的字符串添加const声明。

答案 1 :(得分:0)

尝试以下三组输入: 1. file1大于file2 2. file2比file1大 3. file1的大小等于file2。 让我们知道错误被复制时的情况以及错误被复制的情况。 我想在这个阶段你会自己解决问题。 如果不, 写出再现错误的(可能的最小)file1和file2的内容。

答案 2 :(得分:-1)

列举的一些问题:

- 您假设file1和file2具有相同的大小或者至少file1的大小为&lt; = file2 (在另一种情况下会导致行if (file2[i].size() < file1[i].size()) {中的内存访问无效)并没有检查功能。至少添加断言或检查 - 您正在初始化file3 ,并在函数中稍后编制索引 - 另一个问题是当file1 [i]和file2 [i]具有相同的长度时发生的情况,该选项不在if-else中覆盖,封面选项是&lt;和&gt;但不是== - 您使用file3[i][x]等语句访问无效内存,因为file3[i]中的字符串初始化为空,因此,不包含任何字符。

如果不知道编码算法的确切步骤,我就能得到更接近的结果

#include <iostream>
#include <vector>
#include <boost/lexical_cast.hpp>

using namespace std;

std::vector<std::string> Encode(std::vector<std::string> &file1,
    std::vector<std::string> &file2) {

    assert(file1.size() <= file2.size());
    std::vector<std::string> file3(file1.size());
    std::string temp;

    for (unsigned int i = 0; i < file1.size(); i++) {
        for (unsigned int x = 0; x < file1[i].size(); x++) {
            int enc = 0;
            if (file2[i].size() <= file1[i].size()) {
                for (unsigned int t = 0; t < file2[i].size(); t++) {
                    enc = (int)file1[i][x] + (int)file2[i][t];
                }
            }
            else if (file2[i].size() > file1[i].size()) {
                enc = (int)file1[i][x] + (int)file2[i][x];
            }

            if (enc > 126) {
                file3[i] += (enc % 127);
            }
            else {
                file3[i] += (enc + 32);
            }
        }
    }
    return file3;
}

int main(int argc, char *argv[]) {
    std::vector<std::string> a{ "1", "2", "3" };
    std::vector<std::string> b{ "6", "7", "8" };

    for (const auto& s : a)
        std::cout << s << std::endl;

    for (const auto& s : b)
        std::cout << s << std::endl;

    auto c = Encode(a, b);
    for (const auto& s : c)
        std::cout << s << std::endl;
    return 0;
}