C++ C++;cin后程序突然结束
我正在编写代码来获取非常大的斐波那契数的最后一位,比如fib(239),等等。。我使用字符串来存储数字,从头到尾获取各个字符,然后将它们转换为int,然后将值存储回另一个字符串。我无法测试我写的东西,因为我的程序在C++ C++;cin后程序突然结束,c++,C++,我正在编写代码来获取非常大的斐波那契数的最后一位,比如fib(239),等等。。我使用字符串来存储数字,从头到尾获取各个字符,然后将它们转换为int,然后将值存储回另一个字符串。我无法测试我写的东西,因为我的程序在std::cin>>n之后突然关闭行。 这是我到目前为止所拥有的 #include <iostream> #include <string> using std::cin; using std::cout; using namespace std; char
std::cin>>n之后突然关闭代码>行。
这是我到目前为止所拥有的
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using namespace std;
char get_fibonacci_last_digit_naive(int n) {
cout << "in func";
if (n <= 1)
return (char)n;
string previous= "0";
string current= "1";
for (int i = 0; i < n - 1; ++i) {
//long long tmp_previous = previous;
string tmp_previous= previous;
previous = current;
//current = tmp_previous + current; // could also use previous instead of current
// for with the current length of the longest of the two strings
//iterates from the end of the string to the front
for (int j=current.length(); j>=0; --j) {
// grab consectutive positions in the strings & convert them to integers
int t;
if (tmp_previous.at(j) == '\0')
// tmp_previous is empty use 0 instead
t=0;
else
t = stoi((string&)(tmp_previous.at(j)));
int c = stoi((string&)(current.at(j)));
// add the integers together
int valueAtJ= t+c;
// store the value into the equivalent position in current
current.at(j) = (char)(valueAtJ);
}
cout << current << ":current value";
}
return current[current.length()-1];
}
int main() {
int n;
std::cin >> n;
//char& c = get_fibonacci_last_digit_naive(n); // reference to a local variable returned WARNING
// http://stackoverflow.com/questions/4643713/c-returning-reference-to-local-variable
cout << "before call";
char c = get_fibonacci_last_digit_naive(n);
std::cout << c << '\n';
return 0;
}
在10后面有一个新行,10是我为n输入的。
谢谢你的帮助。节日快乐 首先计算斐波那契数,然后使用std::to_string()
将int
转换为std::string
。在下文中,您可以使用最后一个索引上的[]
运算符提取最后一个数字
int fib(int i)
{
int number = 1;
if (i > 2) {
number = fib(i - 1) + fib(i - 2);
}
return number;
}
int main() {
const int i = 10;
const int f = fib(i);
const std::string s = std::to_string(f);
if (!s.empty()) {
std::cout << "fibonacci of " << i << " = " << f << " | last digit: " << s[s.size() - 1] << std::endl;
}
std::cin.sync(); std::cin.get();
return 0;
}
intfib(inti)
{
整数=1;
如果(i>2){
数字=fib(i-1)+fib(i-2);
}
返回号码;
}
int main(){
常数i=10;
常数int f=fib(i);
常量std::string s=std::to_string(f);
如果(!s.empty()){
std::cout在Mac上运行此代码我得到:
libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: basic_string before callin funcAbort trap: 6
代码本身最明显的问题出现在以下行中:
for (int j=current.length(); j>=0; --j) {
原因:
如果您正在执行类似current.at(j)的操作,则会立即崩溃。例如,字符串“blah”的长度为4,但位置4处没有字符
tmp_previous的长度可能与current不同。例如,从8到13调用tmp_previous.at(j)将崩溃
此外,正如其他人所指出的,如果你唯一感兴趣的是最后一位数字,那么你不需要麻烦地遍历每一个数字的每一位。这里的诀窍是只记住上一个数字和当前数字的最后一位数字,因此大数决不是问题,你不必做类似sto的事情i、 我之所以发布这篇文章,是因为您对问题的理解似乎比您试图部署的解决方案的选择要落后。这是一个问题的例子,在这个问题中,解决方案方法的选择及其实现的问题或障碍混淆了您试图解决的实际问题
你试图计算N的最后一个数字,其中N可能是合群的
求解fib(N)
的迭代解为:
unsigned fib(unsigned n)
{
if (n <= 1)
return n;
unsigned previous = 0;
unsigned current = 1;
for (int i=1; i<n; ++i)
{
unsigned value = previous + current;
previous = current;
current = value;
}
return current;
}
为此:
current = value % 10;
给我们一个几乎相同的算法,但每次迭代时只“记住”最后一个数字:
unsigned fib_last_digit(unsigned n)
{
if (n <= 1)
return n;
unsigned previous = 0;
unsigned current = 1;
for (int i=1; i<n; ++i)
{
unsigned value = previous + current;
previous = current;
current = value % 10; // HERE
}
return current;
}
下面是我们通过fib\u last\u digit
运行算法时得到的结果:
0:0
1:1
2:1
3:2
4:3
5:5
6:8
7:3
8:1
9:4
10:5
11:9
12:4
13:3
14:7
15:0
16:7
17:7
18:4
19:1
20:5
这应该会给你一种信心的萌芽,这可能是你所寻求的算法,你可以完全放弃字符串操作。作为先前答案的替代方法,可以使用字符串加法。
我用10万斐波那契数测试了它,它在几秒钟内就可以正常工作。只使用最后一个数字就可以解决更大的数字的问题。对于所有需要斐波那契数的人,这里有一个算法:
std::string str_add(std::string a, std::string b)
{
// http://ideone.com/o7wLTt
size_t n = max(a.size(), b.size());
if (n > a.size()) {
a = string(n-a.size(), '0') + a;
}
if (n > b.size()) {
b = string(n-b.size(), '0') + b;
}
string result(n + 1, '0');
char carry = 0;
std::transform(a.rbegin(), a.rend(), b.rbegin(), result.rbegin(), [&carry](char x, char y)
{
char z = (x - '0') + (y - '0') + carry;
if (z > 9) {
carry = 1;
z -= 10;
} else {
carry = 0;
}
return z + '0';
});
result[0] = carry + '0';
n = result.find_first_not_of("0");
if (n != string::npos) {
result = result.substr(n);
}
return result;
}
std::string str_fib(size_t i)
{
std::string n1 = "0";
std::string n2 = "1";
for (size_t idx = 0; idx < i; ++idx) {
const std::string f = str_add(n1, n2);
n1 = n2;
n2 = f;
}
return n1;
}
int main() {
const size_t i = 100000;
const std::string f = str_fib(i);
if (!f.empty()) {
std::cout << "fibonacci of " << i << " = " << f << " | last digit: " << f[f.size() - 1] << std::endl;
}
std::cin.sync(); std::cin.get();
return 0;
}
std::string str\u add(std::string a,std::string b)
{
// http://ideone.com/o7wLTt
大小n=最大值(a.大小(),b.大小());
如果(n>a.size()){
a=字符串(n-a.size(),'0')+a;
}
如果(n>b.size()){
b=字符串(n-b.size(),'0')+b;
}
字符串结果(n+1,'0');
字符进位=0;
std::transform(a.rbegin(),a.rend(),b.rbegin(),result.rbegin(),[&carry](字符x,字符y)
{
字符z=(x-'0')+(y-'0')+进位;
如果(z>9){
进位=1;
z-=10;
}否则{
进位=0;
}
返回z+'0';
});
结果[0]=进位+0';
n=结果。首先查找“0”中的“非”;
if(n!=string::npos){
结果=结果substr(n);
}
返回结果;
}
标准::字符串str_fib(大小i)
{
std::string n1=“0”;
std::string n2=“1”;
对于(大小\u t idx=0;idxSTD:CUT尝试用<代码> -g/<代码>标志和调试,用<代码> gdB <代码>。我检查过,我没有GDB。所以我必须安装它。你做的完全错了。除了C++语言的错综复杂之外,为了知道17795 + 23417的最后一个数字是2,你不需要计算17795和23417的总和。你不需要EVE。n需要记住17795和23417。你只需要5和7。我同意@n.m。算法应该是简单地计算下一个值,即value=current+previous
,然后previous=current
,然后current=value%10
,只使用无符号整数类型(任何,真的)在最后一次迭代之后,代码<>当前< /代码>的值将是你所要查找的数字。关于C++的使用,你需要理解两件事:(1)类型转换是告诉编译器关闭,因为你知道得更好,并且(2)你不太清楚。因此,在你的编程生涯的这个阶段不要使用类型转换。它们是在浪费你的时间。特别是,你对(string&)(tmp_previous.at(j))的使用
etc.是未定义的行为,不管你怎么看它都没有意义。这个fib函数不起作用。这是我最后一次使用它。其目的是能够处理像fib(300)这样的超大fib数。这就是我选择使用字符串的原因。因此,您基本上需要手动添加字符串。首先尝试封装此函数:std::string add(std::string a,std::string b)
,然后在fib()
函数中从所有int
更改为std:.string
?是的,我将继续这样做以完成它
unsigned fib_last_digit(unsigned n)
{
if (n <= 1)
return n;
unsigned previous = 0;
unsigned current = 1;
for (int i=1; i<n; ++i)
{
unsigned value = previous + current;
previous = current;
current = value % 10; // HERE
}
return current;
}
0:0
1:1
2:1
3:2
4:3
5:5
6:8
7:13
8:21
9:34
10:55
11:89
12:144
13:233
14:377
15:610
16:987
17:1597
18:2584
19:4181
20:6765
0:0
1:1
2:1
3:2
4:3
5:5
6:8
7:3
8:1
9:4
10:5
11:9
12:4
13:3
14:7
15:0
16:7
17:7
18:4
19:1
20:5
std::string str_add(std::string a, std::string b)
{
// http://ideone.com/o7wLTt
size_t n = max(a.size(), b.size());
if (n > a.size()) {
a = string(n-a.size(), '0') + a;
}
if (n > b.size()) {
b = string(n-b.size(), '0') + b;
}
string result(n + 1, '0');
char carry = 0;
std::transform(a.rbegin(), a.rend(), b.rbegin(), result.rbegin(), [&carry](char x, char y)
{
char z = (x - '0') + (y - '0') + carry;
if (z > 9) {
carry = 1;
z -= 10;
} else {
carry = 0;
}
return z + '0';
});
result[0] = carry + '0';
n = result.find_first_not_of("0");
if (n != string::npos) {
result = result.substr(n);
}
return result;
}
std::string str_fib(size_t i)
{
std::string n1 = "0";
std::string n2 = "1";
for (size_t idx = 0; idx < i; ++idx) {
const std::string f = str_add(n1, n2);
n1 = n2;
n2 = f;
}
return n1;
}
int main() {
const size_t i = 100000;
const std::string f = str_fib(i);
if (!f.empty()) {
std::cout << "fibonacci of " << i << " = " << f << " | last digit: " << f[f.size() - 1] << std::endl;
}
std::cin.sync(); std::cin.get();
return 0;
}