【譯/解/注】Strings Mix

Given two strings s1 and s2, we want to visualize how different the two strings are. We will only take into account the lowercase letters (a to z). First let us count the frequency of each lowercase letters in s1 and s2.

原題地址: https://www.codewars.com/kata/5629db57620258aa9d000014/train/javascript
譯者等級:

codewars.com
codewars.com

題目等級:
codewars.com
codewars.com

本文意圖: 題目翻譯 + 答案的注解
如有侵權(quán), 請聯(lián)系本文作者

有兩個字符串 s1铃在、s2花墩,我們想要展現(xiàn)他倆有什么不同。我們將僅充分考慮小寫字母(如:a-z)舅逸。首先讓我們統(tǒng)計一下 s1划鸽、s2 每個小寫字母的出現(xiàn)次數(shù)序芦。

s1 = "A aaaa bb c"

s2 = "& aaa bbb c d"

s1 has 4 'a', 2 'b', 1 'c'

s2 has 3 'a', 3 'b', 1 'c', 1 'd'

在 s1靡狞、s2 中褪那,‘a(chǎn)’ 的最大出現(xiàn)次數(shù)是 4 來自 s1半醉;‘b’ 的最大出現(xiàn)次數(shù)是 3 來自 s2疚俱。接下來,我們將不考慮最大出現(xiàn)次數(shù)小于或等于 1 的字母缩多。

我們可以整理 s1呆奕、s2 在接下來字符串中的不同:“1:aaaa/2:bbb”11:aaa 代表字符串 s1 以及 aaaa 是由于 a 的最大出現(xiàn)次數(shù)是 4。相同的方式 2:bbb 代表字符串 s2 以及 bbb 是由于 b 的最大出現(xiàn)次數(shù)是 3衬吆。

該任務(wù)是生成一個字符串梁钾,其中 s1 或 s2 的小寫字母的最大出現(xiàn)次數(shù)如果嚴(yán)格大于 1,則顯示為最大出現(xiàn)次數(shù); 這些字母將以字符串的數(shù)量作為前綴逊抡,它們在 : 后以最大的次數(shù)出現(xiàn)姆泻。如果最大出現(xiàn)次數(shù)在 s1 和 s2 中相同,則前綴為 =:冒嫡。

在結(jié)果中拇勃,子字符串(子字符串為例 2:nnnnn 或 1:hhh; 它包含前綴)將會以其長度的遞減順序排列,當(dāng)它們有相同長度的按升序排列順序排列(字母和數(shù)字——更精確地按codepoint排序);不同的組將被“/”分開孝凌。參見示例和 “示例測試”方咆。

希望其他的例子能讓這個更清楚。

s1 = "my&friend&Paul has heavy hats! &"
s2 = "my friend John has many many friends &"
mix(s1, s2) --> "2:nnnnn/1:aaaa/1:hhh/2:mmm/2:yyy/2:dd/2:ff/2:ii/2:rr/=:ee/=:ss"

s1 = "mmmmm m nnnnn y&friend&Paul has heavy hats! &"
s2 = "my frie n d Joh n has ma n y ma n y frie n ds n&"
mix(s1, s2) --> "1:mmmmmm/=:nnnnnn/1:aaaa/1:hhh/2:yyy/2:dd/2:ff/2:ii/2:rr/=:ee/=:ss"

s1="Are the kids at home? aaaaa fffff"
s2="Yes they are here! aaaaa fffff"
mix(s1, s2) --> "=:aaaaaa/2:eeeee/=:fffff/1:tt/2:rr/=:hh"

Note for Swift

譯者注: 本節(jié)不做翻譯

The prefix =: is replaced by E:

s1 = "mmmmm m nnnnn y&friend&Paul has heavy hats! &"
s2 = "my frie n d Joh n has ma n y ma n y frie n ds n&"
mix(s1, s2) --> "1:mmmmmm/=:nnnnnn/1:aaaa/1:hhh/2:yyy/2:dd/2:ff/2:ii/2:rr/E:ee/E:ss"

譯者注: 這里是自己嘗試的解答

/**
 * 輔助工具函數(shù)
 * 傳入字符串蟀架,用于為字符計數(shù)
 * @param {*} s 
 */
function m(s) {
    let o = {};

    /**
     * 遍歷每一個字符
     * 將字符串轉(zhuǎn)為數(shù)組瓣赂,并遍歷元素
     */
    s.split('').map((v) => {
        /**
         * 根據(jù)題目要求榆骚,僅統(tǒng)計小寫字母
         */
        if (v >= 'a' && v <= 'z') {
            o[v] = o[v] || 0;
            o[v] += 1; 
        }
    });
    return o;
}

/**
 * 主內(nèi)容
 * @param {*} s1 
 * @param {*} s2 
 */
function mix(s1, s2) {
    let ret = [];
    let s = 'abcdefghijklmnopqrstuvwxyz';
    
    /**
     * 獲取兩個字符串中的字符計數(shù)
     */
    let a1 = m(s1);
    let a2 = m(s2);
    
    /**
     * 將小寫字母集遍歷
     */
    s.split('').map((v) => {
        let n,z;
        
        /**
         * 初始化當(dāng)前小寫字母統(tǒng)計數(shù)
         */
        a1[v] = a1[v] || 0;
        a2[v] = a2[v] || 0;

        /**
         * 小于或等于 1 不做統(tǒng)計
         */
        if (a1[v] <=1 && a2[v] <= 1) return;

        /**
         * 用于得出 : 前為 1/2/=,以及字母重復(fù)次數(shù)
         */
        if (a1[v] > a2[v]) {
            n = '1';
            z = a1[v];
        } else if (a1[v] < a2[v]) {
            n = '2';
            z = a2[v];
        } else {
            n = '=';
            z = a2[v];
        }

        /**
         * 將符合條件的值加入集合
         */
        ret.push({
            n,
            z,
            v
        });
    });
    
    /**
     * 按照題目要求排序
     */
    ret.sort((m, n) => {
        /**
         * 根據(jù)字母重復(fù)次數(shù)降序
         */
        if (m.z - n.z) return -(m.z - n.z);

        /**
         * 字母數(shù)相同的情況钩述,按照 1/2/= 排序
         */
        if (m.n > n.n) return 1;
        if (m.n < n.n) return -1;

        /**
         * 在 1/2/= 相同的情況下寨躁,按照字母升序
         */
        if (m.v > n.v) return 1;
        if (m.v < n.v) return -1;

        /**
         * 保險返回,應(yīng)該無效
         */
        return 0;
    });

    /**
     * 將結(jié)果集合格式化
     */
    return ret.map((v) => {
        /**
         * 形如
         *  1:aaaaa
         */
        return v.n + ':' + (new Array(v.z + 1).join(v.v));
    }).join('/');
}

譯者注: 截止 2017.10.10, 獲得 [Best Practices] 最多的答案
譯者注: 截止 2017.10.10, 獲得 [Clever] 最多的答案
巧了牙勘,同一個

原答案觀摩

function mix(s1, s2) {
  var counter = s => s.replace(/[^a-z]/g,'').split('').sort().reduce((x,y)=> (x[y] = 1 + (x[y]||0), x),{});
  s1 = counter(s1); s2 = counter(s2);
  var res = [], keys = new Set(Object.keys(s1).concat(Object.keys(s2)));
  keys.forEach(key => {
    var c1 = s1[key]||0, c2 = s2[key]||0, count = Math.max(c1, c2);
    if (count>1) {
      var from = [1, '=', 2][Math.sign(c2-c1)+1];
      var str = [...Array(count)].map(_=>key).join('');
      res.push(from+':'+str);
    }
  });
  return res.sort((x, y) => y.length - x.length || (x < y ? -1 : 1)).join('/');
}

解析注釋

function mix(s1, s2) {
    /**
     * 輔助工具函數(shù)
     * 傳入字符串,用于為字符計數(shù)
     * @param {*} s 
     */
    var counter = s => s
        // 使用正則篩選去掉小寫字母外的字符
        .replace(/[^a-z]/g,'')
        .split('')
        .sort()
        // ?? 使用 reduce 一步將統(tǒng)計結(jié)果輸入
        .reduce((x,y)=> (x[y] = 1 + (x[y]||0), x),{});

    /**
     * 獲取兩個字符串中的字符計數(shù)
     */
    s1 = counter(s1); s2 = counter(s2);

    /**
     * ?? 合并兩者統(tǒng)計結(jié)果所禀,并使用 Set 去重
     * 與我的答案相比方面,省去了對全部小寫字母的遍歷
     */
    var res = [], keys = new Set(Object.keys(s1).concat(Object.keys(s2)));
    keys.forEach(key => {
        var c1 = s1[key]||0, c2 = s2[key]||0, count = Math.max(c1, c2);
        if (count>1) {
            /**
             * ?? 使用 Math.sign 得出 1/2/=
             */
            var from = [1, '=', 2][Math.sign(c2-c1)+1];

            /**
             * 得到字母重復(fù)
             */
            var str = [...Array(count)].map(_=>key).join('');

            /**
             * 將格式化結(jié)果推入集合
             */
            res.push(from+':'+str);
        }
    });

    /**
     * ?? 直接使用總長度 + 首字母排序,不需要提前排序
     */
    return res.sort((x, y) => y.length - x.length || (x < y ? -1 : 1)).join('/');
}

做到最后色徘,譯者本人還有點小激動恭金。
雖然高票答案仍然讓我學(xué)到了不少。
但基本思路是一致的褂策,豈不是非常自豪?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末横腿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子斤寂,更是在濱河造成了極大的恐慌耿焊,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,080評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遍搞,死亡現(xiàn)場離奇詭異罗侯,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)溪猿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評論 3 385
  • 文/潘曉璐 我一進(jìn)店門钩杰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人诊县,你說我怎么就攤上這事讲弄。” “怎么了依痊?”我有些...
    開封第一講書人閱讀 157,630評論 0 348
  • 文/不壞的土叔 我叫張陵避除,是天一觀的道長。 經(jīng)常有香客問我抗悍,道長驹饺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,554評論 1 284
  • 正文 為了忘掉前任缴渊,我火速辦了婚禮赏壹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘衔沼。我一直安慰自己蝌借,他們只是感情好昔瞧,可當(dāng)我...
    茶點故事閱讀 65,662評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著菩佑,像睡著了一般自晰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上稍坯,一...
    開封第一講書人閱讀 49,856評論 1 290
  • 那天酬荞,我揣著相機(jī)與錄音,去河邊找鬼瞧哟。 笑死混巧,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的勤揩。 我是一名探鬼主播咧党,決...
    沈念sama閱讀 39,014評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼陨亡!你這毒婦竟也來了傍衡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,752評論 0 268
  • 序言:老撾萬榮一對情侶失蹤负蠕,失蹤者是張志新(化名)和其女友劉穎蛙埂,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體虐急,經(jīng)...
    沈念sama閱讀 44,212評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡箱残,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,541評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了止吁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片被辑。...
    茶點故事閱讀 38,687評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖敬惦,靈堂內(nèi)的尸體忽然破棺而出盼理,到底是詐尸還是另有隱情,我是刑警寧澤俄删,帶...
    沈念sama閱讀 34,347評論 4 331
  • 正文 年R本政府宣布诽里,位于F島的核電站炕泳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜匕积,卻給世界環(huán)境...
    茶點故事閱讀 39,973評論 3 315
  • 文/蒙蒙 一箍铲、第九天 我趴在偏房一處隱蔽的房頂上張望藻三。 院中可真熱鬧苗踪,春花似錦、人聲如沸帚戳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至偏友,卻和暖如春蔬胯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背位他。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評論 1 266
  • 我被黑心中介騙來泰國打工氛濒, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鹅髓。 一個月前我還...
    沈念sama閱讀 46,406評論 2 360
  • 正文 我出身青樓泼橘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親迈勋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,576評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 在C語言中,五種基本數(shù)據(jù)類型存儲空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 3,333評論 0 2
  • String類和正則表達(dá)式 今天的主要內(nèi)容 Scanner類概述Scanner獲取數(shù)據(jù)出現(xiàn)的小問題及解決方案 St...
    須臾之北閱讀 1,923評論 0 3
  • version():mysql版本user():用戶名database():數(shù)據(jù)庫名@@datadir:讀取數(shù)據(jù)庫...
    lokisteven閱讀 1,018評論 0 1
  • 12.01_常見對象(Scanner的概述和方法介紹) A:Scanner的概述 B:Scanner的構(gòu)造方法原理...
    dreamkong閱讀 232評論 0 1
  • 一醋粟、set集合【了解】 1.概述 和數(shù)學(xué)上的集合基本是一樣的靡菇,特點:不允許有重復(fù)元素,可以進(jìn)行交集米愿,并集厦凤,差集的運...
    墨雨love薏雪閱讀 668評論 0 0