C 程序在CIN之后突然结束
C++ Program abruptly ends after cin
我正在编写代码以获取非常大的斐波那契数字的最后一位数字,例如fib(239)等。开始然后将它们转换为int,而不是将值存储回另一个字符串。我无法测试我写的内容,因为我的程序在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) == ' ')
// 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;
}
输出始终相同。无论我输入什么,输出始终相同。这是我用来运行代码及其输出的行。
$ g++ -pipe -O2 -std=c++14 fibonacci_last_digit.cpp -lm
$ ./a.exe
10
10之后有一个newline,而10是我输入的n。感谢任何帮助。和节日快乐!
我正在发布此信息,因为您对问题的理解似乎正在倒退到您试图部署的解决方案的选择。这是一个XY问题的一个示例,一个问题,解决方案方法的选择方法以及其实现的问题或障碍,使您要解决的实际问题混淆了。
您正在尝试计算fibonacci编号的最终数字,其中n可能是群体。斐波那契序列的基本理解告诉您
fib(0) = 0 fib(1) = 1 fib(n) = fib(n-1) + fib(n-2), for all n larger than 1.
求解其 value 的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;
}
一切都很好,但是一旦N
导致我们选择的数据类型的存储功能溢出(在上述情况下,大多数32位平台上的unsigned
将在仅47个迭代后溢出)。
,但我们不需要每次迭代的实际fib
值。我们只需要每个迭代的最后一位数字。好吧,Base-10 Last Digit非常容易从任何未签名的值中获得。对于我们的示例,只需替换以下内容:
current = value;
与此:
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;
}
现在current
始终拥有先前总和的最后一位数字,无论是否超过10款,实际上与我们无关。一旦我们有下一个迭代可以使用它来计算两个单个正数的总和不得超过18个,而再次,我们只需要从那的最后一个数字 next 迭代等。这一直持续到我们迭代多次要求,完成后,最终答案将出现。
验证
我们知道前20个左右的斐波那契数字看起来像这样,通过 fib
:
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
这是我们通过fib_last_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
应该给您带来萌芽的信心感,这可能是您寻求的算法,您可以完全放弃字符串操作。
在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_p_previous的长度可能与当前不同。例如,当您从8到13时,呼叫tmp_previous.at(j)将崩溃。
另外,正如其他人所指出的那样,如果您唯一感兴趣的是最后一位数字,那么您就不需要遇到循环浏览每个数字的每个数字的麻烦。这里的诀窍是只记住上一个和当前的最后一位数字,因此大量的数字绝不是问题,您不必做诸如Stoi之类的事情。
作为先前答案的替代方案是字符串添加。我用斐波那契数的100000进行了测试,并且在短短几秒钟内就可以正常工作。仅与最后一位数字一起工作可以解决您的问题,从而确定更大的数字。对于所有需要斐波那契号的人,这里是一个算法:
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;
}
首先计算fibonacci编号,然后使用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;
}
避免使用关键字using
的重复。
还考虑在数字变大时从int
切换到long
或long long
。由于斐波那契数为正,也使用unsigned
。
- 为什么在这个代码结束循环中没有得到结束
- 试图对缓存进行跨步测试,但程序并没有结束
- MPI突然停止了对多个核心的操作
- 当调用switch语句中的函数时(即使函数不包含循环),似乎是永不结束的循环的问题
- 为什么擦除方法会影响结束方法
- 根据用户输入用字母填充矢量,并将"开始"和"结束"放在四肢
- 删除映射和分割错误中的一个过去结束元素
- 如何使用 SFML 在贪吃蛇游戏中定义游戏结束?
- 为什么我的两个 cin 语句没有在程序结束时运行?
- 在函数结束后使用指向变量的指针是否安全?
- C ++尝试并捕获未结束的程序
- 为什么我的程序在输入某个形状的面积的测量值后没有结束?
- 取消引用结束指针到数组类型的一个
- 如何在 c++ 中确定一条指令(以字节为单位)在哪里结束,另一条指令从哪里开始?
- 结束另一个线程中使用的对象的生存期
- 全局向量导致 C++ 程序结束时出现段错误
- 当存在空单元格时,用于 c++ 的 Tsv 文件解析器会突然结束
- C 程序在CIN之后突然结束
- 如何在Linux中正确报告另一个进程的突然结束
- 代码无法打印出整个字符串并突然结束