• 7855阅读
  • 13回复

求一个算法 [复制链接]

上一主题 下一主题
离线sbtree
 
只看楼主 倒序阅读 楼主  发表于: 2009-07-22
问题描述如下:
一个文本格式的数据文件,行尾以换行符号('\n')结束,每行包含相同数量的数值,他们被一个特殊字符分割开的,而小数点可能是逗号或者点号,每行的数值不一定全是浮点数,可能包含正数,现在要解决的是,如何给定一个算法,找出用来分隔每个数值的特殊字符,希望达人指教
windows 7 + VC++2008 + Qt4.5.2
离线sbtree
只看该作者 1楼 发表于: 2009-07-23
给个数据的例子吧, 逗号作为小数点,分号作为分隔符,每行四个数值,下面是两行数据,文本格式,行尾有换行符'\n':
1;2,35;1,22E-2;-258,98
1,2;5,35;0,36;253
前提是
1.事先并不知道小数点是用逗号表示的,最好算法也能分析出来
2.数值间的分号分隔符也是未知的,待求得
3.每行数据个数未知,但个数相同
已知的内容包括
1.每行包含相同数目的数值,可能是整数或有理数(正常表示法或者科学计数法),行尾有'\n'
2.数值是用文本描述的,他们之间有一个分隔符
3.数值中的小数点符号可能是逗号或者点号。小数点和分隔符一定不相同。
实际上这是要求做一个智能的分析而得出准确的数据。可以想象一下,根据已知的条件,我们的思维可以迅速获取到准确的数据,我的算法就是要求实现这个思维过程。
windows 7 + VC++2008 + Qt4.5.2
离线rqzrqh

只看该作者 2楼 发表于: 2009-07-23
想ing
离线sakiola
只看该作者 3楼 发表于: 2009-07-23
1,2;5,35;0,36;253
你这个例子怎么说都说不通啊
你说逗号是小数点 我还说分号是小数点呢 逗号是分隔符呢 不一样吗

如果实际得到的数值中没有特殊的字符的话 是没办法区分的 也就是说 只有两个符号是没办法说通的 其实我的意思是说 要用区分 就用一定能肯定的符号来区分 假如说负号 我可以肯定这个就是负号 而不是分隔符啦小数点啦的

简单的说 突破口就是“从明显的 已知符号入手解析”
例如 用你的例子来说 如果有个;34;-345,45;不管怎么说 负号能获取到得时候 前边的符号如果不是E、不是数字就一定是分隔符 你滴明白?

当然 可能负号的前边还可能有别的东西 具体是什么就要看你的数据可能包含什么了 反正总体思路是这样地
NB才是王道
离线rqzrqh

只看该作者 4楼 发表于: 2009-07-23
while (非文件结束符)  {
         if (非第一行)  {
             if (每行个数大于1) {
             .....
             }
             else { //每行个数为1
                          ...
                        }
         }
         else {  //第一行
                  .....
                 }
}
  
[ 此帖被rqzrqh在2009-07-23 10:54重新编辑 ]
离线rqzrqh

只看该作者 5楼 发表于: 2009-07-23
判断的时候和已经存起来的separate_sign和float_sign比较
因为基本上根据前几行就能判断出分隔符和小数符,
增加后续的检测速度
本次数值检测标志end,每次开始前要把end标志为0,表示未结束
小数标识符float_sign
numinline=100000;   每一行数值个数,初试化为很大
lineoneflags=1;  用来标识是否是第一行,第一行结束后设置为-1,只用一次
下面是非第一行每行个数为1的代码



      //把每一行只有一个数值的放后面是因为基本上每一行都是超过1个数值的,优先判断一行有多个数值的。
       if (numinline==1) {
                 end=0;            //表明要进入检测数值
            while(end==0) {
        getchar();
             //只有一行只需要检测换行符就可以了,因为能进入一行循环的肯定是没有sepatate_sign的              
         if (getchar没有出现特殊字符) {
           记录检测到的数值;
           continue;
         }
         else  if(getchar=float_sign) {                        
           记录检测到的数值
            continue;    
          }
         //数字出现概率高,把换行符的检测放最后面
        else if (getchar=='\n') {                        
           num++;
                          end=1;  //标志这次数值检测已经结束
               }
        else  { //也有可能之前检测出每一行只有一个数值的时候并没有检测出有小数
             float_sign=getchar;
              continue;
          }
            
    }
  剩下的事楼主自己做吧      
            
[ 此帖被rqzrqh在2009-07-23 10:59重新编辑 ]
离线xymail110
只看该作者 6楼 发表于: 2009-07-23
先说我的思路吧:

        统计每一行的所有特殊字符出现的次数,应该只有两种特殊字符 : 逗号或者分号,分别记为xi, yi,表示每一行逗号和分号的数量.
        因为每一行的特殊字符的个数是相等的,所以整个文本统计下来,肯定有xo=x1=...=xn(或者y0=y1=...=yn),满足这个条件的就是分号了.那么另一种字符就是逗号.

        但是特殊情况是每逗号和分号的个数都是一样的,此时,按照楼主给出的条件是不可能区分出这良种符号的.
[ 此帖被xymail110在2009-07-23 13:51重新编辑 ]
学无止境
离线sbtree
只看该作者 7楼 发表于: 2009-07-23
谢谢大家的提示,
rqzrqh的描述看上去比较详细,但前提条件是要先判断出小数符和分隔符,而我的问题恰恰在这里,这个判断是如何实现的。按照你的说法“基本上根据前几行就能判断出分隔符和小数符”,这是怎么判断的?一旦判断出小数符和分隔符,后面你按顺序分析的方法就水到渠成了。还要注意另一个可能,就是小数点是点号,逗号是分隔符的情况。
xymail110的思路是我目前正在考虑的,利用统计的方法判断分隔符。有个问题就是当每个数值都带有小数点的话,每行小数点的个数也会相同,所以我想在这种情况下可以考虑分隔符会比小数点的个数少1,因为最后一个数值后面没有分隔符,只是一个明确的换行符。还有一种考虑,就是小数符的个数最多比分隔符大1。利用这个特征,希望能区分出来。
sakiola的想法有点局限,我给出两行数据而不是一行,是为了能够进行比较,但第二行的确是一个很极端的例子。通过对多行数据的对比,对特殊符号的数量进行分析,以区别出小数点和分隔符。不过你说的对负号的判断倒是一个可以利用的特征。
[ 此帖被sbtree在2009-07-23 16:01重新编辑 ]
windows 7 + VC++2008 + Qt4.5.2
离线rqzrqh

只看该作者 8楼 发表于: 2009-07-23
分隔符可以是任意符号?小数标符也是任意符号?只是在同一文本内两者不同?
离线sentimental
只看该作者 9楼 发表于: 2009-07-23
扫描一下第一行,获得特殊字符队列, 逗号和点号优先级最低就是了
离线sbtree
只看该作者 10楼 发表于: 2009-07-23
rqzrqh的方法在进入第一次数值检测的时候,还没有明确的小数符号,如何判断else  if(getchar=float_sign)
windows 7 + VC++2008 + Qt4.5.2
离线sbtree
只看该作者 11楼 发表于: 2009-07-23
引用第8楼rqzrqh于2009-07-23 16:32发表的  :
分隔符可以是任意符号?小数标符也是任意符号?只是在同一文本内两者不同?

分隔符可以是任意在数值中不会出现的符号,小数点只能是逗号或点,在同一文本中两者一定不同。在小数点是点的情况下,逗号也可能是分隔符
windows 7 + VC++2008 + Qt4.5.2
离线sbtree
只看该作者 12楼 发表于: 2009-07-23
引用第9楼sentimental于2009-07-23 16:34发表的  :
扫描一下第一行,获得特殊字符队列, 逗号和点号优先级最低就是了

你说的逗号和点号优先级最低,是指什么?是在扫描的过程中作最后对这两个符号进行判断吗?

可以明确一点的是,作为一个通用算法,仅仅通过一行数据是无法判断出来的。例如下面只有一行的数据
1.2,3.5,4
单纯从这行数据分析,其结果可能有两种
1. 点号是小数点,逗号是分隔符, 那么数据将是  1.2    3.5     4
2. 逗号是小数点,点号是分隔符, 那么数据将是  1       2.3     5.4
这是一种最极端的情况,遇到这种情况,只能在去检测其它行数据。当然如果整个文件都是这种数据,只有人为设定小数点符号的优先级别了。
windows 7 + VC++2008 + Qt4.5.2
离线sbtree
只看该作者 13楼 发表于: 2010-07-21
这个算法实际上是为了实现对csv文件的通用智能分析算法的一部分,如果对世界各国的数字格式了解的话,可能会理解得更深刻一点。
windows 7 + VC++2008 + Qt4.5.2
快速回复
限100 字节
 
上一个 下一个