合并排序字符串向量C ++

时间:2017-03-14 10:10:06

标签: c++ string vector mergesort

大家好,我是一个递归的菜鸟,我感觉就像撞在墙上一样。我观看了一些视频,阅读了这一章,并试图找出这个问题的答案超过6个小时,现在没有运气。我的教授给了我们以下代码,我们必须从那里修改它。注意:我们正在从文件中读取52k个单词,然后使用此算法对它们进行排序。不确定这是否重要,但我认为我会添加信息以防万一 包括

using namespace std;

vector<int> MergeUsingArrayIndices(const vector<int> & LHS,
                               const vector<int> & RHS)
{
vector<int> ToReturn;

int i = 0;  // LHS index
int j = 0;  // RHS index

while ((i < LHS.size()) && (j < RHS.size()))
{
    if (LHS[i] < RHS[j])
    {
        ToReturn.push_back(LHS[i]);
        ++i;
    }
    else
    {
        ToReturn.push_back(RHS[j]);
        ++j;
    }
}

while (i < LHS.size())
{
    ToReturn.push_back(LHS[i]);
    ++i;
}

while (j < RHS.size())
{
    ToReturn.push_back(RHS[j]);
    ++j;
}

return ToReturn;
}

除了现在我们必须从一个向量中完成这项工作。这就是我到目前为止所拥有的。

vector<string> MergeUsingArrayIndices(vector<string> & LHS,
int START, int MID, int MIDPLUSONE, int END)
{

    vector<string> ToReturn;
    int i = 0;  // LHS index
    int j = MIDPLUSONE;  // RHS index

    while ((i <= MID) && (j <= END))
    {
        if (LHS[i] < LHS[j])
        {
            ToReturn.push_back(LHS[i]);
            ++i;
        }
        else
        {
            ToReturn.push_back(LHS[j]);
            ++j;
        }
    }

    while (i <= MID)
    {
        ToReturn.push_back(LHS[i]);
        ++i;
    }

    while (j <= END)
    {
        ToReturn.push_back(LHS[j]);
        ++j;
    }
    for (int k = 0; k < ToReturn.size(); ++k)
    {
        LHS[k] = ToReturn[k];
    }
    return ToReturn;

}

另外这是函数之前的调用。

void MergeSort(vector<string> & VECTOR, int START, int END)
{

if (END > START)
{
    int MID = (START + END) / 2;
    MergeSort(VECTOR, START, MID);
    MergeSort(VECTOR, MID + 1, END);
    MergeUsingArrayIndices(VECTOR, START, MID, (MID+1), END);
}
}

void Merge(std::vector<string> & VECTOR)
{

MergeSort(VECTOR, 0, VECTOR.size()-1);
}

Console Screen Shot

基本上它是排序但不是很好,因为并非所有内容都按字母顺序排列。这只是列表中的一小部分单词。

谢谢你,最诚挚的问候,

不要结婚了。

更新:PNKFELIX 它尝试了以下内容;

        vector<string> ToReturn;
        int i = START;       // LHS index
        int j = MIDPLUSONE;  // RHS index

    while (i <= MID && j <= END)
    {
        if (LHS[i] <= LHS[j])
        {
            ToReturn[START] = LHS[i];
            //ToReturn.push_back(LHS[i]);
            ++START;
            ++i;
        }

等等但是这使得代码变得更糟,所以我确信这不是你所指的。我已经好几天试图解决这个问题,我无法入睡......

你指出的一件事是困扰我,因为我知道为什么它没有发生但是无法解决的是电话

我猜这就是为什么你用苹果,梨,橙,香蕉的例子。 (顺便说一句非常聪明)。你可以带马去水但不能喝水。但是,我仍然没有看到如何解决这个问题?我试过替换我的i = 0;因为我现在看到这可能是比较右侧的罪魁祸首,因为它应该从那个位置开始,但它实际上使我的代码变得更糟?我还缺少什么?

当教授做这样的事情的时候,我有很多事情要做,不能忍受(我的社区学院对CIS来说并不好,而我的教授之前从未教过这门课程)。我无法休息,直到我弄明白,但教科书远远超出了我的头脑(教授甚至在学期开始时为教科书道歉,说这对我们来说太先进,但这是他们给他的)并且完全使用了不同的方法(两个单独的数组而不是一个向量)。我应该怎么做START?我花了很多时间在这上面,我很想知道答案。也许这让我很懒,但有一点你只能想到这么多东西。我喜欢学习,但这不是在学习,因为我达到了我的极限。我错过了一些东西,并且不知道如何开始检查它是​​什么。我假设每个矢量比较的右侧没有排序,但我该如何解决?是因为开始并不总是零(例如:右手边)?我不擅长排序算法(因为我不是很聪明(虽然我研究分配))因为它是,这是一个新的转折。这就像把一个破碎的泡沫分类交给某人并要求他们办公桌检查它,修复它的错误,并使它更有效但他们以前从未见过有人工作过。

2 个答案:

答案 0 :(得分:0)

使用strcmp(LHS [i],LHS [j])&lt; 0 in if condition

答案 1 :(得分:0)

这样一个问题的好处是,这里没有特定的C ++。可以使用提议的代码并将其移植到几乎任何其他合理的语言(例如JavaScript),然后在那里进行调试以确定出现了什么问题。

任何程序的一个好习惯是记录代码的假设和不变量。如果这些不变量足够简单,您甚至可以通过assert语句检查它们是否在代码本身内。

所以,让我们看一下:从查看MergeUsingArrayIndices调用MergeSort的方式来看,你的方法似乎是递归的分而治之:你首先将输入分成两个中点元素,对分割输入的每一边进行排序,然后合并这两部分。

从这个高级描述中,我们可以识别出在MergeUsingArrayIndices时必须保留的几个不变量:必须对LHS的左半部分进行排序,并且还必须对LHS的右半部分进行排序。当我们合并向量时,我们可以检查这两个条件是否成立,这可以帮助我们找出出错的地方。

我把原始代码尽可能忠实地移植到Rust(我的首选编程语言),然后添加了一些断言和一些print语句,以便我们可以看到断言失败的位置。

  • (还有一个我上面忘记提到的更改:我还从MergeUsingArrayIndices中删除了未使用的返回值。您构建的数组仅用作临时存储,稍后会复制到{ {1}};您永远不会使用返回值,因此我们可以完全从函数的类型中删除它。)

以下是正在运行的游戏围栏中的代码:

https://play.rust-lang.org/?gist=bd61b9572ea45b7139bf081cb51dc491&version=stable&backtrace=0

一些主要问题:

  • 当报告LHS实际上不小于LHS[i]时,断言比较哪些索引?
  • 打印输出报告何时应在某些子范围对矢量进行排序:0 ... 0,1 ... 1,0 ... 1等。您在上面找到的指数(假设它们与我找到的指数相同)不属于这些子范围之一;所以我们实际上没有理由声称LHS[i+1]小于LHS[i]!那么发生了什么,为什么代码认为它们应该属于向量的有序子范围?
  • 强烈提示第一:我发出警告说编译器会发出关于代码的问题。
  • 强烈提示第二:尝试进行我在LHS[i+1]功能上方评论中留下的练习。