自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Erlang實戰(zhàn)文本排版

開發(fā) 開發(fā)工具
本文主要是通過Erlang實現(xiàn)簡單的文本排版,借此學習Erlang、熟悉Erlang。希望對大家有所幫助。

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

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

  要求如下:

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

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

看起來比較復(fù)雜,其實思路比較簡單:

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

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

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

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

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

結(jié)果如下:

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

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

【編輯推薦】

  1. Erlang之父Joe Armstrong訪談:程序調(diào)試與啤酒
  2. Scala和Erlang,以及多核主導的未來
  3. Erlang面向分布與并發(fā)的編程語言
  4. 看Erlang中Actor模型的執(zhí)行方式和優(yōu)劣
  5. Erlang視點:并行計算和云計算
責任編輯:彭凡 來源: 博客園
相關(guān)推薦

2012-05-07 15:32:46

Erlang

2012-05-14 13:58:19

Erlang

2021-02-26 20:01:30

LaTex排版LaTeX排版

2025-02-12 00:35:24

WinForm框架工具

2010-09-10 14:54:12

DIV排版

2010-09-17 14:13:20

SIP業(yè)務(wù)Erlang

2021-02-24 16:50:07

LaTex排版表格

2021-02-24 16:15:20

LaTeX排版LaTeX列表

2012-05-07 08:47:25

Erlang

2021-09-27 14:44:48

鴻蒙HarmonyOS應(yīng)用

2023-11-20 22:07:51

PythonPDF

2021-02-20 20:58:04

LaTeXTeXstudio排版文檔

2014-12-08 14:15:48

Material De字體排版

2010-03-22 14:45:40

云計算

2009-04-22 09:20:26

Erlang并發(fā)函數(shù)式

2009-07-30 10:59:44

Scala和Erlan多核

2012-08-16 09:07:57

Erlang

2012-12-28 14:23:12

Android開發(fā)TextView

2010-09-08 17:20:42

CSS

2010-09-14 10:41:24

DIV+CSS排版
點贊
收藏

51CTO技術(shù)棧公眾號