from : http://www.cnblogs.com/chagel/archive/2009/02/01/1381820.html   附評論

最近在論壇閑逛,先后參與了兩題算法趣味題目。

  1. 題目1是要求算一任意長度字符串中不同的字符以及它的個數。
  2. 題目2是把一段字符串用“右起豎排”的古文格式輸出。

題目難度不大,都是針對字符串的操作,邏輯比較簡單,靈活在對不同語言、語法的掌握程度。(原文分別在:1,2。)

看了大家用C++、C#、Java等語言的實現,總感覺牛刀殺雞太麻煩,有興趣的朋友可以自己寫寫看或者直接看原文的網友回復。我最近一段時間Python寫的比較多,讀到這些題目時候,就有一種躍躍欲試的沖動。因為我知道用Perl,Python,Ruby等動態語言來做這類題目,會是非常理想的。后來我做了這兩道題目,結果也令人滿意,代碼之簡潔保持在所有答案的前列。

先看第一題Python解答:

dic = {}
for s in "abcdefgabc":
dic[s] = 1 if s not in dic else (dic[s]+1)
print '\n'.join('%s,%s' % (k, v) for k, v in dic.items())

輸出結果:

a,2
c,2
b,2
e,1
d,1
g,1
f,1

Python的四行代碼分別做了dictionary的聲明,賦值,字符串的遍歷,以及高效拼接。

如果還沒有看出它的簡潔和強大的話,請看第二題的解法:

def main(offset=6):
    string = u'靜夜思 李白床前明月光,疑似地上霜。舉頭望明月,低頭思故鄉。090131'
a = [[' ']*offset for row in xrange(offset)]
for i in xrange(offset):
for j in xrange(offset):
a[i][j] = string[j + i*offset]
b = [[r[col] for r in a[::-1]] for col in xrange(len(a[0]))]
    print '\n'.join([u'┊'.join(unicode(c) for c in row)for row in b])

輸出結果:

0┊低┊舉┊疑┊床┊靜
9┊頭┊頭┊似┊前┊夜
0┊思┊望┊地┊明┊思
1┊故┊明┊上┊月┊
3┊鄉┊月┊霜┊光┊李
1┊。┊,┊。┊,┊白

這題如果用C#等實現,代碼要在20行以上。下面我簡單介紹一下這幾行代碼:

  1. 第3行,在Python里面二維“數組”通過嵌套list來實現,這里初始化一個6行6列的二維數組;
  2. 第7行,我們把“矩陣”順時針旋轉了90度(行列置換,并且對置換后的行首尾對調-這里的::-1就是用來置換一個list的trick);
  3. 最后一行,我們把數組里的每行中元素,每行之間分別用兩個不同字符拼接起來。join方法以及for..in..語句在python中是相當常見的用法。

通過這兩題,我們看到Python在處理字符串時候的十分靈活方便,雖然一種語言的好壞不應完全靠是否簡潔來衡量,但對于我個人而言,Python是目前我用過的最好的語言。而且對于趣味題來說,這不就是我們解題的趣味所在嗎?

Tag標簽: python
Posted on 2009-02-01 07:01 Chagel 閱讀(1328) 評論(14)  編輯 收藏 網摘

Feedback

#1樓    回復  引用  查看    

2009-02-01 09:50 by Jeffrey Zhao      
從CSDN的趣味題學C# 3.0
http://www.cnblogs.com/JeffreyZhao/archive/2009/02/01/1381867.html

#3樓    回復  引用  查看    

2009-02-01 10:24 by JimLiu      
老趙的代碼不錯,我改進下
第二個
static void Count(string message) {
message
.GroupBy(c => c)
.ToList()
.ForEach(p => Console.WriteLine("{0}, {1}", p.Key, p.Count()));
}

這樣似乎更爽一些,呵呵

#4樓    回復  引用  查看    

2009-02-01 10:26 by Jeffrey Zhao      
@JimLiu
那個select的確可以省,我是習慣于先搞出數據來,然后添加行為,而不是在行為里繼續計算

#5樓    回復  引用  查看    

2009-02-01 10:34 by JimLiu      
@Jeffrey Zhao
呵呵,是因為先select了好重復用吧,習慣問題,我的喜歡就根據題目變化。

#5樓    回復  引用    

2009-02-01 11:59 by young5335 [未注冊用戶]
a="abcdefgabc"
myset=set(a)
for s in myset:
print(str(a.count(s))+" "+s)

2 a
2 c
2 b
1 e
1 d
1 g
1 f

#6樓    回復  引用    

2009-02-01 13:24 by young5335 [未注冊用戶]
import math
colSize=6
string="靜夜思 李白床前明月光,疑似地上霜。舉頭望明月,低頭思故鄉。0901311"
iLen=math.ceil(len(string)/colSize)
l=list(reversed(([string[i*colSize:i*colSize+colSize].ljust(colSize,' ') for i in range(0,iLen)])))
for i in range(colSize):
for j in range(iLen):
print(l[j][i],end=" ")
print()

python語法我真的快忘光光了.

#7樓    回復  引用    

2009-02-01 13:28 by young5335 [未注冊用戶]
要改成跟樓主一樣的分隔符,把end="┊"

#8樓    回復  引用    

2009-02-01 13:44 by young5335 [未注冊用戶]
PHP的:
$a="abcdefgabc";
$result=count_chars($a,1);
array_walk($result,create_function('$v,$k','echo chr($k)." ".$v."<br/>";'));

a 2
b 2
c 2
d 1
e 1
f 1
g 1

#9樓    回復  引用  查看    

2009-02-02 00:00 by Icebird      
JavaScript:

var s = "hello";
var arr = s.split('');
var o = {};
var c;
for (var i = 0; i < arr.length; i++)
{
o[arr[i]] = (o[arr[i]] ? o[arr[i]] : 0) + 1;
}

var result = "";
for (var p in o)
{
result += p + ", " + o[p] + "\r\n";
}

alert(result);

#10樓    回復  引用    

2009-02-02 10:22 by 賴勇浩 [未注冊用戶]
>>> from collections import defaultdict
>>> adict = defaultdict(int)
>>> for s in "abcdefgabc":
... adict[s] += 1
...
>>> print '\n'.join('%s,%s' % (k, v) for k, v in adict.iteritems())
a,2
c,2
b,2
e,1
d,1
g,1
f,1

#11樓    回復  引用    

2009-02-02 11:21 by young5335 [未注冊用戶]
a="abcdefgabc"
b={}
a.each_char { |x|b.store(x,a.count(x)) }
b.each {|k,v| puts k+" "+v.to_s}

#12樓    回復  引用    

2009-02-02 15:18 by hehehe [未注冊用戶]
試試Groovy:

('abcdefgabc' as List).groupBy{it}.each{k, v -> println "$k, ${v.size()}"}

#13樓    回復  引用    

2009-02-02 15:37 by hehehe [未注冊用戶]
試試Groovy(第二題):

def a = '床前明月光 疑似地上霜 舉頭望明月 低頭思故鄉'.tokenize(' ')

5.times{row ->
println a.collect{it[row]}.reverse().join('|')
}


低|舉|疑|床
頭|頭|似|前
思|望|地|明
故|明|上|月
鄉|月|霜|光

#14樓    回復  引用    

2009-02-02 16:04 by zealtea [未注冊用戶]
txt = u"靜夜思 李白床前明月光,疑似地上霜。舉頭望明月,低頭思故鄉。"
offset = 6

a =[i[::-1] for i in zip(*[txt[i:i+offset] for i in range(0, len(txt), offset)])]

for i in a:
print "|".join(i)