【问题标题】: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 虽然这是真的,但在大多数情况下,您可能会想出一个几乎正确的解决方案,但一个小错误会使您无法获得输出。在这种情况下,类似上述答案的参考非常有帮助。

标签: javascript anagram


【解决方案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;
      }
      

      【讨论】:

        猜你喜欢
        • 2016-04-07
        • 1970-01-01
        • 2017-10-09
        • 2021-01-11
        • 2017-03-16
        • 2019-05-02
        • 1970-01-01
        • 2013-08-18
        相关资源
        最近更新 更多