Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从随机三重字母表猜单词_Java_C++_String_Algorithm_Data Structures - Fatal编程技术网

Java 从随机三重字母表猜单词

Java 从随机三重字母表猜单词,java,c++,string,algorithm,data-structures,Java,C++,String,Algorithm,Data Structures,我遇到了这个问题,我还不能找到它的完整解决方案。 (来源:) 给定函数 getRandomTripplet() 它返回字符串中的随机三元组字母。你不知道 使用此函数的调用了解字符串必须正确 猜猜绳子。也给出了字符串的长度 假设字符串是helloworld,函数getRandomTriplet将 归还类似的东西 他在世界各地 该函数维护字母的相对顺序。它会的 永不回头 ohl,因为在字符串中h在o之前。因为w在e之后 字符串未知,您只知道字符串的给定长度 到目前为止,我的方法是运行getRando

我遇到了这个问题,我还不能找到它的完整解决方案。 (来源:)

给定函数

getRandomTripplet()

它返回字符串中的随机三元组字母。你不知道 使用此函数的调用了解字符串必须正确 猜猜绳子。也给出了字符串的长度

假设字符串是helloworld,函数getRandomTriplet将 归还类似的东西

他在世界各地

该函数维护字母的相对顺序。它会的 永不回头

ohl,因为在字符串中h在o之前。因为w在e之后

字符串未知,您只知道字符串的给定长度

到目前为止,我的方法是运行getRandomTripplet()1000次,然后通过获取出现率最高的字符(概率>1/10)查找重复字符

我走对了吗

谢谢你的帮助。
干杯

在未能产生概率解之后,我提出了这种蛮力方法,似乎能产生正确的结果。对于某些字符串,总的状态空间相当大,但算法最终会收敛:)

这可能不是最有效的解决方案,但似乎确实奏效了。下面的代码可以优化很多,但作为一个例子,它应该足够了

#include <iostream>
#include <set>
#include <functional>

#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>

// the input string for the random generator
static const std::string input("hello_world");
// an "empty" character (something not present in the input string)
static const char empty = '?';
// a constant with the input length (the only known fact about the input in the algorithm)
static const unsigned length = input.length();

// randomization algorithm returning triplets
std::string randomTriplet() {
    static boost::random::mt19937 gen;
    static boost::random::uniform_int_distribution<> dist(0, input.length()-1);

    std::set<unsigned> indices;
    while(indices.size() < 3)
        indices.insert(dist(gen));

    std::string result;
    for(auto i : indices)
        result.push_back(input[i]);
    return result;
}

// runs a functor for all possible combinations of input triplet acc to the rules
void allCombinations(const std::string& triplet, const std::function<void(const std::string&)>& functor) {
    for(unsigned a=0;a<length-2;++a)
        for(unsigned b=a+1;b<length-1;++b)
            for(unsigned c=b+1;c<length;++c) {
                std::string tmp(length, empty);
                tmp[a] = triplet[0];
                tmp[b] = triplet[1];
                tmp[c] = triplet[2];

                functor(tmp);
            }
}

// tries to merge two strings, and returns an empty string if it is not possible
std::string putTogether(const std::string& first, const std::string& second) {
    std::string result(length, empty);

    for(unsigned a=0;a<length;++a)
        if((first[a] == empty) || (first[a] == second[a]))
            result[a] = second[a];
        else if(second[a] == empty)
            result[a] = first[a];
        else if(first[a] != second[a])
            return std::string();

    return result;
}

// run a single iteration on a set of input states and a triplet
std::set<std::string> iterate(const std::set<std::string>& states, const std::string& triplet) {
    std::set<std::string> result;

    // try all combinations on all states
    for(auto& s : states) {
        allCombinations(triplet, [&](const std::string& val) {
            // and if merge is possible, insert it into the result
            const std::string together = putTogether(s, val);
            if(!together.empty())
                result.insert(together);
        });
    };

    return result;
}

int main(int argc, char*argv[]) {
    // the current state space (all possible strings given the observations so far)
    std::set<std::string> states;

    // initialisation - take the first triplet and generate all combinations of this triplet
    allCombinations(randomTriplet(), [&](const std::string& val) { states.insert(val); });

    // iterate - the number of iterations is rather arbitrary. We cannot stop when the solution
    //   count is 1, because some input strings (like "hello world", where the double l and o 
    //   are the problem) don't have a unique solution
    for(unsigned a=0;a<10000;++a) {
        states = iterate(states, randomTriplet());
        std::cout << "\r" << "iteration #" << a << ", combinations count = " << states.size() << "   " << std::flush;

        // however, if we do find a single solution, we don't have to go on
        if(states.size() == 1)
            break;
    }
    std::cout << std::endl;

    // print them all
    for(const auto& i : states)
        std::cout << i << std::endl;

    return 0;
}

三重L和双O字产生的模糊性,只能用三个字符的观察法来决定。

你使用java还是C++?两者都可以,但我更喜欢java。
iteration #9999, combinations count = 6     
hello_world
helol_world
hlelo_world
hleol_world
lhelo_world
lheol_world