制作两个字符串字谜

Posted

技术标签:

【中文标题】制作两个字符串字谜【英文标题】:make two strings anagrams 【发布时间】:2018-06-07 20:27:44 【问题描述】:

我解决了黑客等级的挑战。它关于如何字谜。我给了两个字符串输入,我必须找到...

打印一个整数,表示您必须删除的字符数,以使两个字符串相互变位。

我已经检测到它是否是字谜和差异。但现在可以做剩下的没有任何想法。请帮助。

function main() 
    var a = readLine();
    var b = readLine();
    var sum1 = 0 ;
    var sum2 = 0 ;

    for (var i= 0; i<= a.length-1; i++ )
        
            sum1 = sum1 + a.charCodeAt(i);
        

       console.log(sum1);


        for (var i= 0; i<= b.length-1; i++ )
        
            sum2 = sum2 + b.charCodeAt(i);
        

       console.log(sum2);

    if(sum1== sum2)
        
            console.log("anagrams");
        
    else
        
            console.log("not anagram");
            var diff = sum1 - sum2;
            console.log(diff);

            /// what to do now ?   
        



【问题讨论】:

不是确定了解如何完成它的编码挑战的一部分吗?当其他人为您回答时,有点违背了目的..... @Claies 虽然这是真的,但在大多数情况下,您可能会想出一个几乎正确的解决方案,但一个小错误会使您无法获得输出。在这种情况下,类似上述答案的参考非常有帮助。 【参考方案1】:

如果您仍在寻找合理的解决方案,我已经在hackerRank 上使用对象方法计算字母的频率解决了这个问题。

function makeAnagrams(a,b)
  let charA=buildcharMap(a)
  let charB=buildcharMap(b)
  let characters=[]
  let counter=0

 for(let char in charA)
   if(charA[char] && charB[char])
     if(charA[char]===charB[char]) //same frequency
        continue;
     
     else
       if(charA[char]>charB[char])
         counter=counter+ charA[char]-charB[char]
       
       else
         counter=counter+ charB[char]-charA[char]
       
      
    
    else
      counter=counter+charA[char]
    
 

  for(let char in charB)
    if(charB[char] && charA[char]===undefined)
        counter=counter+charB[char]
    
  
  return counter;



function buildcharMap(str)
  var charMap=
  for(let char of str)
    if (charMap[char]===undefined)
      charMap[char]=1
    
    else
      charMap[char]+=1
    
  
  return charMap


console.log(makeAnagrams('cde','abc'))

【讨论】:

【参考方案2】:

我已经在hackerearth上解决了这个问题,我采取了稍微不同的方法。

我在这段代码中所做的是检查所有字符,如果字符串中的两个字符相同,则用“@”符号替换字符,然后我计算其中一个字符串中的所有“@”符号即被修改,然后从两个字符串的总长度中减去该计数乘以 2 的值(因为...它们在两个字符串中相似)。

这是我的代码,希望你能把它转换成javascript。 ->

import java.util.Scanner;

public class Anagrams 
    public static void main(String[] args) 
        Scanner scanner = new Scanner(System.in);

        int Testcases = scanner.nextInt();

        String[] str1 = new String[1000];
        String[] str2 = new String[1000];

        //  Taking input
        for (int i = 0; i < Testcases; i++) 
            str1[i] = scanner.next().toLowerCase();
            str2[i] = scanner.next().toLowerCase();
        

        //  For Total Length of both strings
        int TotalLength[] = new int[Testcases];

        //  For counting "@" signs
        int count[] = new int[Testcases];

        //  Loop through TestCases
        for (int i = 0; i < Testcases; i++) 

            TotalLength[i] = str1[i].length() + str2[i].length();

            for (int j = 0; j < str1[i].length(); j++) 
                for (int k = 0; k < str2[i].length(); k++) 
                    //  If both characters are similar, then replace those characters with "@" signs
                    if (str1[i].charAt(j) == str2[i].charAt(k)) 
                        str1[i] = str1[i].replaceFirst(Character.toString(str1[i].charAt(j)),"@");
                        str2[i] = str2[i].replaceFirst(Character.toString(str2[i].charAt(k)),"@");
                    
                
            
        

        //  Counting "@" signs from one string
        for (int i = 0; i < Testcases; i++) 
            count[i] = 0;
            char[] c1 = str1[i].toCharArray();
            for (char c: c1) 
                if(c == '@')
                    count[i]++;
                
            
        

        //  Output
        for (int i = 0; i < Testcases; i++)    
            System.out.println(TotalLength[i] - 2*count[i]);
        

        scanner.close();
    

【讨论】:

【参考方案3】:

您实际上只是在寻找后期频率差异的总和。您可以将频率计入 26 项数组(规则告诉您只有小写数字)。然后从另一个项目中减去每个数组,但项目并将整个事情相加。好像只需要四行代码:

function makeAnagram(a, b) 
  const makeCountArray = (str) => [...str].reduce((a, c) => (a[c.charCodeAt(0) - 97]++, a), Array(26).fill(0))
  let a1 = makeCountArray(a)
  let a2 = makeCountArray(b)
  return a1.reduce((a, c, i) => a + Math.abs(c - a2[i]), 0)


// test case expected: 30
let count = makeAnagram('fcrxzwscanmligyxyvym', 'jxwtrhvujlmrpdoqbisbwhmgpmeoke')
console.log(count)

【讨论】:

这绝对比我想象的要短。似乎它需要“减少”的高级知识。减去 97 有什么意义? @马克迈耶 @UgurYilmaz 97 是a 的值。这确保了数组索引从零开始。 reduce 需要一些练习并习惯,但一旦你这样做了,它就是 javascript 中最有用的功能之一。 你有没有推荐我可以用reduce练习的平台或教程? @马克迈耶 不确定@UgurYilmaz。 MDB 有一个很好的概述:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…【参考方案4】:

这是使用每个字符串中所有 26 个字母的 Map() 的另一种方法

  function makeAnagram(a, b) 
  let result = 0;
  const alphabets = 'abcdefghijklmnopqrstuvwxyz'.split('');

  const getCharCountMap = str => 
    const strArray = str.split('');
    let charMap = new Map();
    alphabets.forEach(alphabet => charMap.set(alphabet, 0));
    strArray.forEach(letter => charMap.set(letter, charMap.get(letter) + 1));
    return charMap;
  ;

  const aMap = getCharCountMap(a);
  const bMap = getCharCountMap(b);

  alphabets.forEach(alphabet => 
    result = result + Math.abs(aMap.get(alphabet) - bMap.get(alphabet));
  );

  return result;

【讨论】:

以上是关于制作两个字符串字谜的主要内容,如果未能解决你的问题,请参考以下文章

字谜不匹配(字符串到列表),Python

这是一个字谜程序,我正在检查两个相同长度的字符串是不是相互字谜

使用 C++ 检查两个字符串是不是是字谜

这段代码在做啥。检查两个字符串的字谜

如何检查两个字符串是不是是字谜?

如何找出字符串的两个相等部分是不是是python中的字谜