这段代码里,if not polyphonse判断里的句子只有在上面的for没有被break时才执行,也就是for循环执行时才执行,这种情况在编程中经常遇到,而python提供了for else循环语句,于是可以修改成:
1 2 3 4 5 6
for item in self.polyphone[key]: if chars.find(item[key]['context']) != -1: result.append(item[key]['pron'].strip()[:-1].lower()) break else : result.append(self.dict[key].split(",")[0].strip()[:-1].lower())
考虑之后,给出了一种解法。为了方便,我们给球编号,1,2,3,4,,,13。 1.首先把1,2,3,4放在左边天平,把5,6,7,8放在右边天平, 2.如果天平一样重,则那个球在剩下的5个球中,其它8个为标准球。之后在这5个球中取3个球,放在左边,取3个标准球放在天平右边,分三种情况 A 如果一样重,则不合格球在剩下的两个球中,对于剩下的两个球,取其中一个出来称,如果偏重或者偏轻,则找到了那个不合格球,如果一样重,则不合格球是剩下的一个(注意,这里我们不能知道它是偏重或者偏轻)。 B 如果左边轻,之后再称一次就可以知道是哪个球偏轻。 C 如果左边重,之后再称一次就可以知道是哪个球偏轻。 3.如果不一样重,则那个球在这8个球中。假设是左边重了,则剩下可能的8种情况,1,2,3,4号偏重,5,6,7,8号偏轻。之后的取法可以这样,左边放三个标准球再加上8号球,右边放5,6,7和4号球。依然分三种情况 A 如果一样重,则1 2 3号球偏重,称一次即可知道结果 B 如果左边重,则5 6 7 号球偏轻,称一次即可知道结果 C 如果左边轻,则8号球偏轻或者4号球偏重,称一次即可知道结果。
if (termsIndexDivisor != -1 && !sr.termsIndexLoaded()) { // If this reader was originally opened because we // needed to merge it, we didn't load the terms // index. But now, if the caller wants the terms // index (eg because it's doing deletes, or an NRT // reader is being opened) we ask the reader to // load its terms index. sr.loadTermsIndex(termsIndexDivisor); }
if (documentMerge) { //Update Dengshilong 2014-09-25 //here is where documentMerge and read FieldCache actually do //read fields and types from start parameters //for every field ,read value from FieldCache , //for numerical field use the correspond byte transform method to build a Field String fieldNamesStr = System .getProperty(Constant.DOCUMENT_MERGE_FIELDS); String typesStr = System .getProperty(Constant.DOCUMENT_MERGE_TYPES); String[] fieldNames = fieldNamesStr.split(","); String[] types = typesStr.split(","); for (; docCount < maxDoc; docCount++) { // NOTE: it's very important to first assign to doc then // pass it to // termVectorsWriter.addAllDocVectors; see LUCENE-1282 Document doc = reader.document(docCount, fieldSelectorMerge); Map typeMap = TypeUtil.TYPE_MAP; for (int i = 0; i < fieldNames.length; i++) { String fieldName = fieldNames[i]; String type = types[i]; Fieldable field = (Fieldable) doc .getFieldable(fieldName); if (field == null) { Types t = (Types) TypeUtil.TYPE_MAP.get(type); switch(t) { case INTEGER: int[] vi = FieldCache.DEFAULT.getInts(reader, fieldName); Field fi = new Field(fieldName, ByteUtil.toArr(vi[docCount]), Store.YES); doc.add(fi); break; case LONG: long[] vl = FieldCache.DEFAULT.getLongs(reader, fieldName); Field fl = new Field(fieldName, ByteUtil.toArr(vl[docCount]), Store.YES); doc.add(fl); break; case FLOAT: float[] vf = FieldCache.DEFAULT.getFloats(reader, fieldName); Field ff = new Field(fieldName, ByteUtil.toArr(vf[docCount]), Store.YES); doc.add(ff); break; case DOUBLE: double[] vd = FieldCache.DEFAULT.getDoubles(reader, fieldName); Field fd = new Field(fieldName, ByteUtil.toArr(vd[docCount]), Store.YES); doc.add(fd); break; } } else { continue; } }
到索引目录下查看,一共有如下几种文件格式。对照http://lucene.apache.org/core/2_9_4/fileformats.html,知道每一种格式的大概用途。 segments.gen, segments_N Segments File 主要保存索引段信息 .fnm Fields 域的元数据信息文件,保存域信息 .fdx Field Index 域数据索引文件,保存指向域数据文件的指针,方便快速访问域数据文件 .fdt Field Data 域数据文件,保存每个文档的字段,域的真正值就是在这里保存 .tis Term Infos 词典文件,记录索引词的信息 .tii Term Info Index 词典索引文件,记录到tis文件的指向,主要是为了加快访问词典文件 .frq Frequencies 文档号与词频文件,记录索引词在文档中的词频 .prx Positions 词位置信息文件,记录索引词的位置信息 .nrm Norms 标准化因子文件,记录文档和域的权重 .tvx Term Vector Index 词向量索引文件,保存到词向量文档文件和词向量域文件的指针 .tvd Term Vector Documents 词向量文档文件,记录文档第一个域与其它域的偏移 .tvf Term Vector Fields 词向量域文件,记录域级别的词向量 .del Deleted Document 记录哪个文档被删除
错误都出现在4.0升级到4.8时。调用栈如下: Caused by: java.lang.IllegalArgumentException: maxValue must be non-negative (got: -1) at org.apache.lucene.util.packed.PackedInts.bitsRequired(PackedInts.java:1180) at org.apache.lucene.codecs.lucene41.ForUtil.bitsRequired(ForUtil.java:243) at org.apache.lucene.codecs.lucene41.ForUtil.writeBlock(ForUtil.java:164) at org.apache.lucene.codecs.lucene41.Lucene41PostingsWriter.addPosition(Lucene41PostingsWriter.java:368) at org.apache.lucene.codecs.PostingsConsumer.merge(PostingsConsumer.java:123) at org.apache.lucene.codecs.TermsConsumer.merge(TermsConsumer.java:164) at org.apache.lucene.codecs.FieldsConsumer.merge(FieldsConsumer.java:72) at org.apache.lucene.index.SegmentMerger.mergeTerms(SegmentMerger.java:389) at org.apache.lucene.index.SegmentMerger.merge(SegmentMerger.java:112) at org.apache.lucene.index.IndexWriter.mergeMiddle(IndexWriter.java:4132) at org.apache.lucene.index.IndexWriter.merge(IndexWriter.java:3728) at org.apache.lucene.index.ConcurrentMergeScheduler.doMerge(ConcurrentMergeScheduler.java:405) at org.apache.lucene.index.ConcurrentMergeScheduler$MergeThread.run(ConcurrentMergeScheduler.java:482)
看代码后,在PostingsConsumer 120行附近,final int position = postingsEnum.nextPosition();,这个position是负的,所以报错。看这附近的代码,知道是对索引词的在文档中的位置信息进行压缩。可是词在文档中的位置不应该是负的,于是报错。问题是,为什么这里会出现负的位置,只能解释是数据问题。一个解决的办法是跳过为负的位置,如此升级确实成功了,只是不知道有没有什么副作用。