我知道像1 3 7 8
这样的比赛的焦点位置。我需要知道他们对应的行号。
示例:file.txt
匹配:X
匹配: 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);
}
}
}
答案 0 :(得分:1)
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,
答案 1 :(得分:1)
首先,您的示例无效 - 示例中的字符X
位于(0,3,9,10)
位置,而不是(1,3,7,8)
。你要将换行符留在你的计算之外,当你应该从0开始时,你将在索引1处开始计数。
将绝对位置与行号相关联的唯一方法是映射换行符的位置以进行比较。像其他人所说的那样,在飞行中这样做并不困难 - 只是缓慢而乏味。如果您要进行多次查找,并且您知道数据在两次之间都不会更改,则应创建静态映射。您可以使用List或Map,但是有一个名为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
。这样我就确保每一行的字符数都包括换行符;必须计算所有字符。 (并且就此而言,我知道不同的行分隔符和代理对存在问题,但为了清楚起见,我将它们留下来。)
您可以通过将Scanner的findWithinHorizon()
方法替换为split()
和'indexOf()`来对文件使用相同的技术。
答案 2 :(得分:0)
每次读取一行时都会递增计数器,而不是每次读取一个字符时。如果您一次只读一个字符,只要看到EOL字符就会递增。
答案 3 :(得分:0)