日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Erlang實(shí)戰(zhàn)文本排版

文本排版大家都并不陌生,并且隨處可見(jiàn),無(wú)論是當(dāng)前的字處理軟件,如Word、PDF等,還是傳統(tǒng)的出版行業(yè),如:書(shū)籍、報(bào)刊、雜志等,都有良好的排版風(fēng)格和樣式。好的排版風(fēng)格讓人耳目一新,有一種繼續(xù)讀下去的沖動(dòng)。本文主要是通過(guò)Erlang實(shí)現(xiàn)簡(jiǎn)單的文本排版,借此學(xué)習(xí)Erlang、熟悉Erlang。

  實(shí)戰(zhàn):文本排版。

  要求如下:

  在代碼中我附了注釋,代碼如下:

 
 
 
 
  1. -module(text_process).
  2. -export([process/2]).
  3. -import(lists,[reverse/1]).
  4. process(FileIn,FileOut) ->
  5.     {Status,Value} = file:open(FileIn,read),
  6.     if
  7.         Status =:= ok ->
  8.             Tokens = readFile(Value), %% 將要處理文本FileIn拆分為單詞列表
  9.             io:format("token :~p~n",[Tokens]),
  10.             writeToFile(FileOut,Tokens), %% 將單詞重新排版輸出到屏幕與文件FileOut
  11.             io:format("~nsuccess!~n");
  12.         Status =/= ok ->
  13.             io:format("Open file error: file doesn't exist!")
  14.     end.    
  15.     
  16. readFile(Value) -> readFile(Value,[]).
  17. readFile(S,Dict) ->
  18.     OneLine = io:get_line(S,''), %%讀取文件的一行
  19.     if
  20.         OneLine =:= eof ->
  21.              io:format("~nCome across the file end, stop!~n"),
  22.              file:close(S),
  23.              Dict;
  24.         OneLine =/= eof ->
  25.             Tokens = string:tokens(OneLine,"\r\t\n "),  %%以空格、回車、換行、制表符為單詞分隔符
  26.             Len = string:len(Tokens),  %%獲得字符串的長(zhǎng)度
  27.             if
  28.                 Len =:= 0 ->  %%遇到空行,停止處理
  29.                     io:format("~nCome across blank line, stop!~n"),
  30.                     file:close(S),
  31.                     Dict;
  32.                 Len =/= 0 ->
  33.                     NewDict = string:concat(Dict,Tokens), %% 將Tokens連接到Dict尾
  34.                     readFile(S,NewDict) %%未讀到空行、EOF,繼續(xù)讀取文本
  35.             end
  36.     end.
  37. writeToFile(FileOut,Tokens) ->
  38.     {ok,S} = file:open(FileOut,write),
  39.     Data = parse(Tokens,[]),
  40.     String  = lineToPara(Data),
  41.     io:format("~n~s~n",[String]),  %% 輸出到屏幕
  42.     io:format(S,"~s~n",[String]). %% 輸出到文件
  43.     %lists:foreach(fun({X}) -> io:format(S,"~s~n",[X]) end, Data).        
  44. lineToPara(Data) -> lineToPara(Data,"").
  45. lineToPara([],Ret) -> Ret;
  46. lineToPara(Data,Ret) ->
  47.     Last = lists:nth(1,Data),
  48.     Element = element(1,Last),
  49.     Temp = Ret ++ Element ++ "\n",
  50.     %io:format("~s",[Temp]),
  51.     lineToPara(lists:delete(Last,Data), Temp).
  52. %%解析單詞列表
  53. parse(Tokens,Contents) ->
  54.     M =50,
  55.     {ALine,RemainToken} = parse_line(Tokens,M),
  56.     if
  57.         length(RemainToken) =:= 0 ->
  58.             Plain = plain(ALine),
  59.             io:format("last line----:~s~n",[Plain]),
  60.             NewContent = lists:append(Contents,[{Plain}]);
  61.         length(RemainToken) =/= 0 ->
  62.             NewContent = lists:append(Contents,[{ALine}]),
  63.             parse(RemainToken,NewContent)
  64.     end.
  65. plain(Last) ->plain(Last, "").
  66.     
  67. plain([], String) -> String;
  68. plain(L, String) ->
  69.     if
  70.         length(L) =:= 1 ->
  71.             Last = lists:nth(1,L),
  72.             NewS = string:concat(String,Last);
  73.         length(L) =/= 1 ->
  74.             First = lists:nth(1,L),
  75.             Temp = string:concat(First," "),
  76.             NewS = string:concat(String,Temp),
  77.             plain(lists:delete(First,L), NewS)
  78.     end.
  79. parse_line(Tokens,M) -> parse_line(Tokens,M,[]).
  80. %% @ Tokens: 當(dāng)前剩余單詞個(gè)數(shù)
  81. %% @ M:每行***字符閥值
  82. %% @ Line: 當(dāng)前單詞行列表
  83. parse_line([],_M,Line) -> {Line,[]};
  84. parse_line(Tokens,M,Line) ->
  85.     if
  86.         length(Line) =:= 0 ->
  87.             Element = lists:nth(1,Tokens),
  88.             NewL = length(Element),
  89.             NewToken  = lists:delete(Element,Tokens),
  90.             parse_line(NewToken,M,[Element]);
  91.         length(Line) =/= 0 ->
  92.             Element = lists:nth(1,Tokens),
  93.             NewL = len(Line)+length(Element)+length(Line),
  94.             case NewL > M of
  95.                     true ->
  96.                         String = toString(Line,M),
  97.                         {String,Tokens};
  98.                     false ->
  99.                         NewLine = lists:append(Line,[Element]),
  100.                         NewToken = lists:delete(Element,Tokens),
  101.                         parse_line(NewToken,M,NewLine)
  102.             end
  103.     end.
  104. %% 排版輸出當(dāng)前行Line數(shù)據(jù)
  105. toString(Line,M) -> 
  106.     Len = len(Line),
  107.     Blank = M - Len,
  108.     %io:format("Blank:~p Len:~p length(Line):~p ~n",[Blank,Len,length(Line)]),
  109.     Ret = justify(Line,Blank,length(Line)),
  110.     io:format("Mess------Ret:~s length:~p~n",[Ret,length(Ret)]),
  111.     Ret.
  112.     
  113. justify(Line,Blank,Len) -> justify(Line,Blank,Len,"").
  114. %% @Line: 一行字符串?dāng)?shù)據(jù)
  115. %% @Blank:需要的空格個(gè)數(shù)
  116. %% @Len: 當(dāng)前行中剩余的單詞個(gè)數(shù)
  117. %% @String: 返回一行矯正結(jié)果
  118. justify(Line,Blank,Len,String) ->
  119.     if
  120.         length(String) =:= 0 ->  %%初始情況
  121.             Temp = lists:nth(1,Line),
  122.             Avg = Blank div Len, %% 計(jì)算單詞之間平均需要Avg個(gè)空格字符
  123.             NewLine = lists:delete(Temp,Line),
  124.             %io:format("1---avg: ~p Blank:~p  Len: ~p~n",[Avg,Blank,Len]),
  125.             case Avg =:= 0 of
  126.                 true ->
  127.                     NewS = while(1,Temp),
  128.                     justify(NewLine,Blank-1,length(NewLine),NewS);
  129.                 false ->
  130.                     NewS = while(Avg,Temp),
  131.                     justify(NewLine,Blank-Avg,length(NewLine),NewS)
  132.             end;
  133.         length(String) =/= 0 -> 
  134.             if
  135.                 length(Line) =:= 1 -> %%一行中***一個(gè)單詞,返回結(jié)果
  136.                     Last = lists:nth(1,Line),
  137.                     NewS = while(Blank,String), %%將剩余的Blank個(gè)字符補(bǔ)全
  138.                     string:concat(NewS,Last);
  139.                 length(Line) =/= 1 ->
  140.                     First = lists:nth(1,Line),
  141.                     Avg = Blank div Len,
  142.                     NewLine = lists:delete(First,Line),
  143.                     %io:format("2---avg: ~p Blank:~p  Len: ~p~n",[Avg,Blank,Len]),
  144.                     case Avg =:= 0 of
  145.                         true ->
  146.                             NewS = while(1,String),
  147.                             justify(NewLine,Blank-1,length(NewLine), string:concat(NewS,First));
  148.                         false ->
  149.                             NewS = while(Avg,String),
  150.                             justify(NewLine,Blank-Avg,length(NewLine), string:concat(NewS,First))
  151.                     end
  152.             end
  153.     end.
  154. %% 功能: 子字符串后面加Count個(gè)空格
  155. while(0,String) -> String;
  156. while(Count,String) ->
  157.     NewS = string:concat(String," "),
  158.     while(Count-1,NewS).
  159. %%統(tǒng)計(jì)一行中字符的個(gè)數(shù)(只包括單詞字符,不包括空格)
  160. len(Line) -> len(Line,0).
  161. len([],Len) -> Len;
  162. len([H|T],Len) ->
  163.     len(T,Len+length(H)).

看起來(lái)比較復(fù)雜,其實(shí)思路比較簡(jiǎn)單:

1.將文本切分單詞列表;

2.設(shè)定一個(gè)閥值M,將每行的字符設(shè)置為M,同時(shí)必須保證單詞不能分割;

我覺(jué)得此程序的難度主要是設(shè)定單詞與單詞之間的空格字符的問(wèn)題,我的思路是:根據(jù)每行中所有單詞所占的字符個(gè)數(shù)不同,求出單詞之間空格的平均Avg個(gè)數(shù),一般情況,單詞與單詞之間的字符個(gè)數(shù)為1,因此justify/4很好的處理了這個(gè)問(wèn)題。

程序運(yùn)行結(jié)果示意圖如下:

test.txt文件內(nèi)容:

結(jié)果如下:

  好了,文檔排版Erlang實(shí)戰(zhàn)就到此為止了。說(shuō)個(gè)小問(wèn)題,我在Erlang實(shí)戰(zhàn):楊輝三角、選擇排序、集合交與并中的實(shí)戰(zhàn)2:選擇排序中不是用了兩次列表逆置來(lái)講一個(gè)元素加入到列表尾嗎,其實(shí)Erlang中模塊lists:append可以解決這個(gè)問(wèn)題,我在本文代碼中多次用到了這個(gè)函數(shù),如:NewLine = lists:append(Line,[Element]),意思就是講Element元素加入到列表尾,但是append函數(shù)的兩個(gè)參數(shù)必須都為列表,因此Element元素需以列表形式加入:[Element],可見(jiàn)世上存在這樣一條真理:只有你不知道的,沒(méi)有不可能發(fā)生的。

原文:http://www.cnblogs.com/itfreer/archive/2012/05/08/Erlang_in_practise_text-process.html


分享名稱:Erlang實(shí)戰(zhàn)文本排版
鏈接URL:http://www.5511xx.com/article/dpidcoh.html