lsmCC 发表于 2023-10-21 18:07:29

两种做法为什么我感觉逻辑上是对的,确答案不一样

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    while(cin>>s,s!="."){
    int len=s.size();
    for(int n=len;len%n==0;n--)
    {
      
            int t=len/n;
            
            // string res=s.substr(0,t);
            string a;
            for(int i=0;i<n;i++)
            {
                a+=s.substr(0,t);;
            }
            if(s==a)
            {
                cout<<n<<endl;
                break;
            }
      
    }
}
   
}
   

下面是正确做法,我把if条件放里面for循环里面去,为什么会不对呢
#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    while(cin>>s,s!="."){
    int len=s.size();
    for(int n=len;n;n--)
    {
      if(len%n==0){
            int t=len/n;
            
            // string res=s.substr(0,t);
            string a;
            for(int i=0;i<n;i++)
            {
                a+=s.substr(0,t);;
            }
            if(s==a)
            {
                cout<<n<<endl;
                break;
            }
      }
      
    }
}
   
}
   

isdkz 发表于 2023-10-21 18:08:00

问题出在第一个做法的for循环条件上。在第一个做法中,循环条件是 for(int n=len;len%n==0;n--) ,即将 len 赋值给 n ,然后判断 len 是否能整除 n 。这样的话,每次循环 n 的值都是不变的,即 len 的值。所以,实际上只进行了一次循环,无论字符串 s 的长度是多少, n 的值都是 s 的长度,所以输出结果始终是 s 的长度。

而在第二个做法中,循环条件是 for(int n=len;n;n--) ,即将 len 赋值给 n ,然后判断 n 是否为真(非零)。这样的话,每次循环 n 的值都会递减,直到为0时循环停止。所以,实际上进行了多次循环,每次循环都会尝试不同的 n 值,直到找到符合条件的 n 值为止。

因此,第二个做法是正确的,而第一个做法是错误的。

陶远航 发表于 2023-10-21 18:08:03

根据您提供的代码片段,两种做法的关键区别在于判断条件的位置不同。

在第一种做法中,判断条件 len%n==0 放在了外层循环中,意味着只有在 len 能够整除 n 的情况下才会执行内层循环。这样可能会导致在某些情况下跳过了正确的解。

而在第二种做法中,判断条件 len%n==0 放在了内层循环中,即在每一次循环时都会进行判断。这样可以保证在任何情况下都会尝试计算结果,并找到正确的解。

因此,第二种做法更加准确,能够得到正确的结果。
请注意,本回答来自GPT-3.5
如果问题已经解决,请设置最佳答案

Mike_python小 发表于 2023-10-21 18:09:10

【代码问题分析】
你提供了两段代码,分别是将条件判断语句放在外层循环和内层循环的位置。让我们进行一下分析:

第一段代码:

#include <bits/stdc++.h>
using namespace std;

int main() {
    string s;
    while(cin >> s, s != ".") {
      int len = s.size();
      for(int n = len; len % n == 0; n--) {
            int t = len / n;
            string a;
            for(int i = 0; i < n; i++) {
                a += s.substr(0, t);
            }
            if(s == a) {
                cout << n << endl;
                break;
            }
      }
    }
}

第二段代码:

#include <bits/stdc++.h>
using namespace std;

int main() {
    string s;
    while(cin >> s, s != ".") {
      int len = s.size();
      for(int n = len; n; n--) {
            if(len % n == 0) {
                int t = len / n;
                string a;
                for(int i = 0; i < n; i++) {
                  a += s.substr(0, t);
                }
                if(s == a) {
                  cout << n << endl;
                  break;
                }
            }
      }
    }
}


【代码问题原因】
这两个版本的代码在逻辑上其实是等价的,应该得到相同的结果。然而,两个版本的代码细微的差异可能导致不同的执行结果,并且两者的性能也略有不同。

问题可能出在这一行代码:

for(int n = len; len % n == 0; n--)



for(int n = len; n; n--)


在第一段代码中,外层循环的条件是len % n == 0,也就是说只会进入满足条件的情况下的循环。而在第二段代码中,外层循环的条件是n,在这种情况下,外层循环不仅在len % n == 0时执行,还包括了其他情况。

因此,如果输入的字符串len不是一个约数,两个版本的代码就会有不同的行为。

【建议修改方式】
为了保证两个版本的代码结果一致,可以将第二段代码修改为:

#include <bits/stdc++.h>
using namespace std;

int main() {
    string s;
    while(cin >> s, s != ".") {
      int len = s.size();
      for(int n = len; n; n--) {
            if(len % n == 0) {
                int t = len / n;
                string a;
                for(int i = 0; i < n; i++) {
                  a += s.substr(0, t);
                }
                if(s == a) {
                  cout << n << endl;
                  break;
                }
            }
      }
    }
}


这样,两个版本的代码应该得到相同的结果。

球一个最佳答案谢谢啦!这对我非常重要!{:10_254:}{:10_254:}{:10_254:}
页: [1]
查看完整版本: 两种做法为什么我感觉逻辑上是对的,确答案不一样