确定Fibonacci字符串的各个字母?

时间:2011-02-04 10:05:09

标签: c++ string algorithm fibonacci

Fibonacci字符串定义如下:

  • 第一个Fibonacci字符串是“a”
  • 第二个Fibonacci字符串是“bc”
  • (n + 2)和Fibonacci字符串是前两个Fibonacci字符串的串联。

例如,前几个Fibonacci字符串是

a
bc
abc
bcabc
abcbcabc

给定行和偏移量的目标是确定该偏移处的字符。更正式地说:

  

输入:由空格分隔的两个整数 - K和P(0 9 ),(&lt;P≤10 9 < / sup>),其中K是Fibonacci字符串的行号,P是行中的位置号。

     

输出:相关测试的所需字符:“a”,“b”或“c”。如果P大于第k行(K≤10 9 ),则必须推导出“无解”

     

示例:

     

输入: 18 58

     

输出: a

我写了这段代码来解决问题:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
    int k, p;
    string s1 = "a";
    string s2 = "bc";
    vector < int >fib_numb;
    fib_numb.push_back(1);
    fib_numb.push_back(2);
    cin >> k >> p;
    k -= 1;
    p -= 1;
    while (fib_numb.back() < p) {
        fib_numb.push_back(fib_numb[fib_numb.size() - 1] + fib_numb[fib_numb.size() - 2]);
    }
    if (fib_numb[k] <= p) {
        cout << "No solution";
        return 0;
    }
    if ((k - fib_numb.size()) % 2 == 1)
        k = fib_numb.size() + 1;
    else
        k = fib_numb.size();
    while (k > 1) {
        if (fib_numb[k - 2] > p)
            k -= 2;
        else {
            p -= fib_numb[k - 2];
            k -= 1;
        }
    }
    if (k == 1)
        cout << s2[p];
    else
        cout << s1[0];
    return 0;
}

这是对的吗?你会怎么做?

5 个答案:

答案 0 :(得分:14)

答案 1 :(得分:1)

我想你的一般想法应该没问题,但是我不知道你的代码将如何处理更大的K值,因为数字会迅速变大,即使使用大型整数库,它也可能永远需要准确地计算斐波那契(10 ^ 9)。

幸运的是,您只被问到前10 ^ 9个字符。该字符串将在第44行(f(44)= 1134903170)上达到许多字符。

如果我没有弄错的话,那里的前10 ^ 9个字符将简单地在第44行和第45行的前缀之间交替,因此在伪代码中:

def solution(K, P):
   if K > 45:
       if K % 2 == 0:
           return solution(44, P)
       else:
           return solution(45, P)
   #solution for smaller values of K here 

答案 2 :(得分:0)

我找到了这个。我没有做预先检查(得到k - fibo字符串的大小来再次测试p因为如果检查成功,你无论如何都要计算它。当然,只要k变大,就可能出现溢出问题(fibo字符串的长度是索引n的指数函数...)。

#include <iostream>
#include <string>

using namespace std;

string fibo(unsigned int n)
{
    if (n == 0)
        return "a";
    else if (n == 1)
        return "bc";
    else
        return fibo(n - 2) + fibo(n - 1);

}

int main()
{
    unsigned int k, p;
    cin >> k >> p;
    --k;
    --p;
    string fiboK = fibo(k);
    if (p > fiboK.size())
        cout << "No solution" << endl;
    else
        cout << fiboK[p] << endl;
    return 0;
}

编辑:好的,我现在看到你的观点,即检查k - 字符串p的哪一部分(即字符串k - 2k - 1,并在需要时更新p。当然,这是做到这一点的好方法,因为正如我上面所说,我天真的解决方案会爆炸得太快。

从算法的角度来看,你的方式对我来说是正确的(节省内存和复杂性)。

答案 3 :(得分:0)

我会计算出第K个Fibonacci字符串,然后检索它的第P个字符。这样的事情:

#include <iostream>
#include <string>
#include <vector>

std::string FibonacciString(unsigned int k)
{
    std::vector<char> buffer;
    buffer.push_back('a');
    buffer.push_back('b');
    buffer.push_back('c');

    unsigned int curr = 1;
    unsigned int next = 2;

    while (k --)
    {
        buffer.insert(
            buffer.end(),
            buffer.begin(),
            buffer.end());

        buffer.erase(
            buffer.begin(),
            buffer.begin() + curr);

        unsigned int prev = curr;
        curr = next;
        next = prev + next;
    }

    return std::string(
        buffer.begin(),
        buffer.begin() + curr);
}

int main(int argc, char** argv)
{
    unsigned int k, p;
    std::cin >> k >> p;

    -- p;
    -- k;

    std::string fiboK = FibonacciString(k);
    if (p > fiboK.size())
        std::cout << "No solution";
    else
        std::cout << fiboK[p];
    std::cout << std::endl;
    return 0;
}

它使用的内存比你的版本多,因为它需要在每个瞬间存储第N和第(N + 1)个斐波那契字符串。但是,由于它非常接近定义,因此它适用于每个值。

k较大且p较小时,您的算法似乎存在问题。测试fib_num[k] < p会使用k = 30p = 1取消引用数组范围之外的项目,不是吗?

答案 4 :(得分:0)

我做了另一个例子,其中每个相应数量的Fibonnaci系列对应于alfabet中的字母。所以1是a,2是b,3是c,5是e ...等:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string a = "abcdefghijklmnopqrstuvwxyz"; //the alphabet
    string a1 = a.substr(0,0); string a2 = a.substr(1,1); string nexT = a.substr(0,0);

    nexT = a1 + a2;

   while(nexT.length() <= a.length())
    {
        //cout << nexT.length() << ", ";             //show me the Fibonacci numbers
        cout << a.substr(nexT.length()-1,1) << ", "; //show me the Fibonacci letters
        a1 = a2;
        a2 = nexT;
        nexT = a1 + a2;
    }
    return 0;
}

输出: a,b,c,e,h,m,u,