反向观察并说

huangapple go评论65阅读模式
英文:

Reverse look and say

问题

I am trying to implement a function that takes a string of digits as input and returns a list of inputs to the look_and_say() function that would have resulted in the given string. Essentially, I am looking for a reverse implementation of the look_and_say() process.

我正在尝试实现一个函数,该函数以数字字符串作为输入,并返回一组输入,这些输入将导致给定字符串通过look_and_say()函数生成。基本上,我正在寻找look_and_say()过程的反向实现。

For example, given the input string "3754", the expected output should be ['77744444', <375 times 4> ], as these would be the inputs that would generate the string "3754" through the look_and_say() process.

例如,给定输入字符串“3754”,期望的输出应该是['77744444', <375 times 4>],因为这些将是通过look_and_say()过程生成字符串“3754”的输入。

The primary constraint of the problem is that each digit in the input string must have a length of 1, while the count of consecutive occurrences can vary in length. It is crucial to note that in the case of "3754", the desired output should not include "37" times "54" since "54" has a length of 2.

问题的主要约束是输入字符串中的每个数字必须具有长度1,而连续发生的次数可以长度不同。需要注意的重要一点是,在“3754”的情况下,期望的输出不应包括“37”次“54”,因为“54”的长度为2。

My current approach involves iterating over the input string and using a mutable list to store the results. Additionally, I utilize a memory HashMap to avoid duplicate entries. However, I have encountered an issue with the output, which didn't concatenate the "777" with the "444" with "3754" as input.

我的当前方法涉及迭代输入字符串,并使用可变列表来存储结果。此外,我使用内存HashMap来避免重复条目。然而,我遇到了一个问题,输出没有将“777”与输入的“3754”的“444”连接起来。

fun sayAndCount(
    string: String,
    counts: MutableList<String> = mutableListOf(),
    memory: HashMap<String, String> = HashMap(),
): List<String> {

    if (memory.containsKey(string)) {
       return listOf()
    }

    val times =  string.substring(0, string.lastIndex)
    val number = string.last()
    val count = number.toString().repeat(times.toInt())
    memory[string] = count

    if (string.length <= 3) {
        return listOf(count)
    }

    for (index in 2 until string.lastIndex) {
        counts.addAll(sayAndCount(string.substring(0, index), counts, memory))
        counts.addAll(sayAndCount(string.substring(index), counts, memory))
    }

    return counts.toList()
}

I would greatly appreciate it if someone could point me in the right direction.

如果有人能指点我正确的方向,我将不胜感激。

英文:

I am trying to implement a function that takes a string of digits as input and returns a list of inputs to the look_and_say() function that would have resulted in the given string. Essentially, I am looking for a reverse implementation of the look_and_say() process.

For example, given the input string "3754", the expected output should be ['77744444', <375 times 4> ], as these would be the inputs that would generate the string "3754" through the look_and_say() process.

The primary constraint of the problem is that each digit in the input string must have a length of 1, while the count of consecutive occurrences can vary in length. It is crucial to note that in the case of "3754", the desired output should not include "37" times "54" since "54" has a length of 2.

My current approach involves iterating over the input string and using a mutable list to store the results. Additionally, I utilize a memory HashMap to avoid duplicate entries. However, I have encountered an issue with the output, which didn't concatenate the "777" with the "444" with "3754" as input.

fun sayAndCount(
    string: String,
    counts: MutableList&lt;String&gt; = mutableListOf(),
    memory: HashMap&lt;String, String&gt; = HashMap(),
): List&lt;String&gt; {

    if (memory.containsKey(string)) {
       return listOf()
    }

    val times =  string.substring(0, string.lastIndex)
    val number = string.last()
    val count = number.toString().repeat(times.toInt())
    memory[string] = count

    if (string.length &lt;= 3) {
        return listOf(count)
    }

    for (index in 2 until string.lastIndex) {
        counts.addAll(sayAndCount(string.substring(0, index), counts, memory))
        counts.addAll(sayAndCount(string.substring(index), counts, memory))
    }

    return counts.toList()
}

I would greatly appreciate it if someone could point me in the right direction.

答案1

得分: 1

以下是您提供的代码的中文翻译:

问题出在您的for循环中:它为子字符串添加结果,而您应该只为完整字符串添加解决方案。

其次,您应该只进行一次递归调用——将左分区视为不再分割更多分区的内容(因为这会导致重复),并仅为字符串的其余部分进行递归调用。

因此,您应该有一个内部循环,遍历递归结果,然后在内部循环体中,您应该用左分区前缀每个结果,以覆盖整个字符串。

最后,您的内存映射应该包含解决方案的列表,而不是像您在memory[string] = count中所做的那样,只包含一个解决方案(字符串)。

以下是JavaScript中的实现:

const memo = new Map;

function solutions(s) {
    if (memo.has(s)) return memo.get(s);
    if (s.length < 2) return [];
    
    const results = [s.at(-1).repeat(+s.slice(0, -1))];
    // 选择左分区的大小
    for (let i = 2; i < s.length - 1; i++) {
        const left = s[i-1].repeat(+s.slice(0, i-1)); 
        for (const right of solutions(s.slice(i))) {
             results.push(left + right);
        }
    }
    memo.set(s, results);
    return results;
}


// 示例:
console.log(solutions("3754"));

请注意,这是提供的JavaScript代码的中文翻译,不包括代码中的注释。

英文:

The problem is in your for loop: it adds results for substrings, while you should only add solutions for the complete string.

Secondly, you should only make one recursive call -- consider the left partition as something you will not split in more partitions (as that would lead to duplicates); and only make the recursive call for the rest of the string.

So you should have an inner loop that iterates over the results coming from recursion, and then in that inner body you should prefix each of those results with the left-partition, so that you cover the whole string.

Finally, your memory map should have the list of solutions, not a single solution (string) like you did with memory[string] = count.

Here it is implemented in JavaScript:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const memo = new Map;

function solutions(s) {
    if (memo.has(s)) return memo.get(s);
    if (s.length &lt; 2) return [];
    
    const results = [s.at(-1).repeat(+s.slice(0, -1))];
    // Choose size of left partition
    for (let i = 2; i &lt; s.length - 1; i++) {
        const left = s[i-1].repeat(+s.slice(0, i-1)); 
        for (const right of solutions(s.slice(i))) {
             results.push(left + right);
        }
    }
    memo.set(s, results);
    return results;
}


// Example:
console.log(solutions(&quot;3754&quot;));

<!-- end snippet -->

答案2

得分: 0

Here is the translation of the code part:

function reverse_look_and_say(s) {
    let result = [];
    for (let i = 0; i < s.length; i += 2) {
        let count = s[i];
        let digit = s[i+1];
        result.push(digit.repeat(parseInt(count)));
    }
    return result;
}

If you have any more code or text to translate, please let me know.

英文:
function reverse_look_and_say(s) {
    let result = [];
    for (let i = 0; i &lt; s.length; i += 2) {
        let count = s[i];
        let digit = s[i+1];
        result.push(digit.repeat(parseInt(count)));
    }
    return result;
}
  1. The function takes a string s as input, which represents the result of a look-and-say sequence.

  2. The function initializes an empty array result to store the final result.

  3. The function enters a for loop that iterates over the input string s in increments of 2.

  4. In each iteration of the loop, the function extracts the count and digit from the input string by indexing s at positions i and i+1, respectively.

  5. The function then appends the digit repeated count times to the result array using the push method and the repeat method.

  6. Once the loop has finished iterating over the entire input string, the function returns the final result array.

This is relatively straightforward I don't understand the use of hashmaps here. If I'm not wrong this should answer your question

答案3

得分: -1

def convert(num):
    num_str = str(num)
    result = ''
    for i in range(len(num_str)):
        result += num_str[i] * (10**i)
    return int(result)

print(convert(3754))
# 77744444
英文:
python
def convert(num):
    num_str = str(num)
    result = &#39;&#39;
    for i in range(len(num_str)):
        result += num_str[i] * (10**i)
    return int(result)

print(convert(3754))
# 77744444

huangapple
  • 本文由 发表于 2023年5月17日 10:51:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76268276.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定