Java: вычислить номер белья из позиции Charwise по номеру "\ n" - PullRequest
0 голосов
/ 22 апреля 2010

Я знаю Charwise положения матчей, как 1 3 7 8.Мне нужно знать их соответствующий номер строки.

Пример: file.txt

Match : X

Mathes: 1 3 7 8.

Хотите: 1 2 4 4

$ cat file.txt
X2
X
4
56XX

[Добавлено: не замечает много совпадений, вероятно, есть более простой способ сделать это со стеками]

$ java testt     
1
2
4
$ cat testt.java 
import java.io.*;
import java.util.*;
public class testt {

    public static String data ="X2\nX\n4\n56XX";
    public static String[] ar = data.split("\n");

    public static void main(String[] args){
        HashSet<Integer> hs = new HashSet<Integer>();
        Integer numb = 1;
        for(String s : ar){
            if(s.contains("X")){
                hs.add(numb);
                numb++;
            }else{
                numb++;
            }
        }   
        for (Integer i : hs){
            System.out.println(i);
        }
    }
}

Ответы [ 4 ]

1 голос
/ 22 апреля 2010

Начнем с того, что ваш пример недопустим - символ X в вашем примере находится в позициях (0,3,9,10), а не (1,3,7,8). Вы исключаете символы перевода строки из своего счета и начинаете счет с индекса 1, когда вы должны начинать с нуля.

Единственный способ связать абсолютные позиции с номерами строк - сопоставить позиции разрывов строк для сравнения. Сделать это на лету, как уже говорили другие, не сложно - просто медленно и утомительно. Если вы собираетесь выполнить несколько поисков, и вы знаете, что данные не изменятся в промежутке времени, вы должны создать статическую карту. Для этого вы можете использовать Список или Карту, но есть класс с именем SizeSequence , который идеально подходит для этой цели. Проверьте это:

import javax.swing.SizeSequence;

public class Test
{
  static SizeSequence createLineMap(String s)
  {
    String[] lines = s.split("(?<=\n)");
    SizeSequence sseq = new SizeSequence(lines.length);
    for (int i = 0; i < lines.length; i++)
    {
      sseq.setSize(i, lines[i].length());
    }
    return sseq;
  }

  public static void main(String[] args) throws Exception
  {
    String input = "X2\nX\n4\n56XX";
    SizeSequence lineMap = createLineMap(input);
    String target = "X";
    int pos = -1;
    while ((pos = input.indexOf("X", pos+1)) != -1)
    {
      System.out.printf("'%s' found in line %d (index %d)%n",
          target, lineMap.getIndex(pos) + 1, pos);
    }
  }
}

выход:

'X' found in line 1 (index 0)
'X' found in line 2 (index 3)
'X' found in line 4 (index 9)
'X' found in line 4 (index 10)

Обратите внимание, как я делю на lookbehind (?<=\n) вместо просто \n. Таким образом я гарантирую, что количество символов каждой строки включает перевод строки; все символы должны быть подсчитаны. (И на этом примечании я знаю, что есть проблемы с различными разделителями строк и суррогатными парами, но я оставлю их для ясности.)

Вы можете использовать ту же технику для файла, заменив метод findWithinHorizon() сканера вместо split() и 'indexOf () `.

1 голос
/ 22 апреля 2010
public static String data ="X2\naaaaXXaaaa\naaaa\naaaaaaX\naaaaaaXaX";
public static String[] lines = data.split("\n");

public static void main(String[] args){
        Map<Integer, List<Integer>> result = new HashMap<Integer, List<Integer>>();

        Integer lineNum = 1;


        for(String s : lines){

            boolean keepSearching = true;
            List<Integer> charPositions=null;
            Integer charNum=0, lastCharNum=0;

            while(keepSearching){

                if (start == true){
                    charNum = s.indexOf("X", lastCharNum);
                    start = false;
                }else{
                    charNum = s.indexOf("X", lastCharNum+1); 
                }

                if(charNum >= 0){
                    if(charPositions== null){
                        charPositions = new ArrayList<Integer>();
                    }
                    charPositions.add(charNum);
                    lastCharNum = charNum;
                }else{
                    keepSearching = false;
                    if(charPositions!= null){
                        result.put(lineNum, charPositions);
                    }
                }
            }

            lineNum++;

        }   
        for (Integer i : result.keySet()){
            System.out.print("Line "+i+" : ");
            for(Integer j : result.get(i)){
                System.out.print("at char "+j+", "); //you should start for the end if you want to print in the right order !
            }
            System.out.println();
        }
    }

Output :
Line 1 : at char 0, 
Line 2 : at char 4, at char 5, 
Line 4 : at char 6, 
Line 5 : at char 6, at char 8,
0 голосов
/ 22 апреля 2010
  1. Гм ... Читая файл построчно, пока не получите совпадение, и увеличив счетчик для каждой строки, которую вы видели?
  2. номер
0 голосов
/ 22 апреля 2010

увеличивает ваш счетчик каждый раз, когда вы читаете строку, а не каждый раз, когда вы читаете символ.Если вы читаете по одному символу за раз, увеличивайте при каждом появлении символа EOL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...