【问题标题】:String & is not reflecting changes made But String does....while passing arguments?String & 没有反映所做的更改但是 String 确实....在传递参数时?
【发布时间】:2014-03-10 03:25:24
【问题描述】:

问题 - 给定一个字符串“0”、“1”和“?”。生成所有可能的字符串,您可以在其中替换“?”用“0”还是“1”?

例如 - 输入 - “0??” 输出 - “000”、“001”、“010”、“011”。

我已经为它写了一个简单的程序——

void gen(string& str, int index)
{
    int i;
    if(str.length() == index)
    {
        cout << str << endl;
        return;
    }
    else
    {
        for(i=index; str[i]!='\0' && str[i]!='?';i++);

        if(str[i] == '?')
        {
            str[i] ='0';
            gen(str,i+1);
            str[i] ='1';
            gen(str,i+1);
        }
    }
    return;
}

int main()
{
    string s ="0??";
    gen(s, 0);
    return 0;
}

它无法正常工作.... 但是,如果您将 void gen(String &, int) 中的参数替换为

void gen(String, int)....

然后它会正常工作..

谁能给我解释一下......

【问题讨论】:

  • “生成”是否意味着将它们打印到控制台?或者类似std::vector&lt;std::string&gt;{ "000", "001", ... } 的东西?
  • 你说“它不能正常工作”......你怎么知道?它会产生什么输出
  • 字符串引用情况下的输出是 - "001" 和 "000" 这是错误的。

标签: c++ string recursion pass-by-reference


【解决方案1】:

当您通过引用传递字符串时,所有对gen() 的递归调用都会对单个字符串进行操作 - 而不是对gen() 的每个调用都单独运行本地副本。对gen() 的每次递归调用都会修改(共享)字符串,删除所有的“?”人物;当该呼叫返回时,不再有“?”剩下要处理的字符,所以它只是终止。

当您按值传递字符串时gen() 函数的每次调用都会获得它自己的字符串本地副本;当函数返回到上一个级别时,它对该字符串所做的任何更改都会被丢弃并忘记。在这种情况下,您的逻辑是正确的。

(还有一个错误导致它在我的 Windows 机器上崩溃,直到我修复它:std::string 不是以空值终止的,所以与其检查std[i] == '\0',不如执行i &lt; str.length() 之类的操作。)

【讨论】:

  • 有什么方法我们不需要复制字符串并且仍然得到正确的答案。就像我们只传递字符串的后缀作为值......
  • 可能有一种避免复制字符串的方法。我的猜测是逻辑会更复杂。
【解决方案2】:

reference 将保持函数调用中更改的值

after set str[1] ='0';

sub call: gen(str,2); will output combination: 000 001

reset str[1] ='1';

str is still 011

gen(str,i+1); output nothing 

希望这段代码能帮到你

#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;
void gen(string& str, int index)
{
    int i;
    if(str.length() == index)
    {
        cout << str << endl;
        return;
    }
    else
    {
        for(i=index; str[i]!='\0' && str[i]!='?';i++);

        if(str[i] == '?')
        {
            printf("before set pos %d to 0: %s\n",i,str.c_str());
            str[i] ='0';
            printf("after set pos %d to 0: %s\n",i,str.c_str());
            gen(str,i+1);
            printf("before set pos %d to 1: %s\n",i,str.c_str());
            str[i] ='1';
            printf("after set pos %d to 1: %s\n",i,str.c_str());

            gen(str,i+1);
        }
    }
    return;
}

int main()
{
    string s ="0??";
    gen(s, 0);
    return 0;
}

输出:

【讨论】:

  • 对于最简单的输入,您的程序无法正常工作"000"ideone.com/DZIgnB
  • @nodakai,我试图解释原因,如果你将 void gen(string& str, int index) 更改为 void gen(string str, int index),输出是正确的
【解决方案3】:

一个简单的解决方案是:

作为每个“?”应该替换为0和1,我们可以看到字符串中会有'2 ** (number of ?)'这样的可能替换。例如,如果我们有三个“?”在字符串中将有 8 个这样的可能替换,如果我们考虑它们的数值,它们将是 0,1,2...,7,其二进制表示将是 000,001,002,....,111。基本上我们应该取数值并将“?”替换为数值中的位。

【讨论】:

  • 那么他必须放弃在输入字符串中支持超过64个?的! (我当然是在开玩笑:)
  • 不完全是,我们有很多数字 :) 。但重点是,假设每个“?”有 52 个可能的字符。并且有n个这样的'?在字符串上,将有 52 ** n 个可能的输出。
猜你喜欢
  • 2021-01-20
  • 2021-10-25
  • 2018-08-17
  • 2015-11-20
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
  • 1970-01-01
相关资源
最近更新 更多