[英]Search string in two dimensional string array java
I have a two dimensional string array look like this: 我有一个二维字符串数组看起来像这样:
The first column contains characters of many strings, other columns are extra data for character. 第一列包含许多字符串的字符,其他列是字符的额外数据。
I want to search a string (maybe change to array character) in this array to get all match indexes (start - end). 我想在这个数组中搜索一个字符串(可能更改为数组字符)以获取所有匹配索引(开始 - 结束)。 For example, when I search with key " next ", the result should be [5 - 8], [13 - 16] (the highlight parts in image above). 例如,当我用键“ next ”搜索时,结果应为[5 - 8],[13 - 16] (上图中的高亮部分)。
Shortly, I need a method look like this: 不久,我需要一个像这样的方法:
public static List<Interval> search(String searchText, String[][] data, int columnsCount, int rowCount){
// Convert search text to String array
String[] searchArr = getStringArray(searchText);
// then search in data
}
// where Interval is:
public class Interval{
public int start;
public int end;
}
Is there any fast way to search like this,cause my data is very large? 是否有任何快速搜索方式,因为我的数据非常大?
Thanks in advance! 提前致谢!
I would recommend to adapt the String[][]
to a CharSequence
. 我建议将String[][]
改编为CharSequence
。 Then you are free to do everything you can do with a CharSequence
and this also means that you can use java.util.regex.Matcher
to search for the string and you don't need to implement an own search algorithm. 然后,您可以自由地使用CharSequence
执行所有操作,这也意味着您可以使用java.util.regex.Matcher
搜索字符串,而无需实现自己的搜索算法。
For example: 例如:
public class Main {
public static void main(String[] args) {
String[][] array2d = createArray();
int charSeqColumn = 0;
CharSequence charSequnce = new Array2DColumnCharSequnce(array2d, charSeqColumn);
System.out.println(charSequnce.toString());
Pattern patttern = Pattern.compile("ext");
Matcher matcher = patttern.matcher(charSequnce);
while (matcher.find()) {
String matchGroup = matcher.group();
int start = matcher.start();
int end = matcher.end() - 1;
String msg = MessageFormat.format("{0} matched at: [{1}] - [{2}]", matchGroup, start, end);
System.out.println(msg);
}
}
private static String[][] createArray() {
String[][] array2d = new String[2][10];
array2d[0][0] = "N";
array2d[0][1] = "e";
array2d[0][2] = "x";
array2d[0][3] = "t";
array2d[0][4] = " ";
array2d[0][5] = "N";
array2d[0][6] = "e";
array2d[0][7] = "x";
array2d[0][8] = "t";
array2d[0][9] = " ";
array2d[1][0] = "H";
array2d[1][1] = "e";
array2d[1][2] = "l";
array2d[1][3] = "l";
array2d[1][4] = "o";
array2d[1][5] = "W";
array2d[1][6] = "o";
array2d[1][7] = "r";
array2d[1][8] = "l";
array2d[1][9] = "d";
return array2d;
}
}
will output 将输出
Next Next
ext matched at: [1] - [3]
ext matched at: [6] - [8]
I would implement the CharSequence
adaption like this 我会像这样实现CharSequence
改编
class Array2DColumnCharSequnce implements CharSequence {
private int column;
private String[][] array2d;
private int endIndex;
private int startIndex;
public Array2DColumnCharSequnce(String[][] array2d, int column) {
this(array2d, column, 0, array2d[column].length);
this.array2d = array2d;
this.column = column;
}
public Array2DColumnCharSequnce(String[][] array2d, int column,
int startIndex, int endIndex) {
this.array2d = array2d;
this.column = column;
this.startIndex = startIndex;
this.endIndex = endIndex;
}
public int length() {
return endIndex - startIndex;
}
public char charAt(int index) {
String charString = array2d[column][startIndex + index];
return charString.charAt(0);
}
public CharSequence subSequence(int start, int end) {
Array2DColumnCharSequnce array2dColumnCharSequnce = new Array2DColumnCharSequnce(
array2d, column, start, end);
return array2dColumnCharSequnce;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(this);
return sb.toString();
}
}
Note : The Array2DColumnCharSequnce
is just a quick implementation and it does not address exception handling yet nor it addresses what happens when there are more than one char in a string column. 注意 : Array2DColumnCharSequnce
只是一个快速实现,它不解决异常处理,也不解决字符串列中有多个char时发生的情况。
Why to use a CharSequence
decorator 为什么要使用CharSequence
装饰器
The difference with adapting the array to a CharSequence
to other approaches is that you use a standard java interface that can be re-used with many other classes and thus is very flexible. 将数组调整为CharSequence
与其他方法的区别在于,您使用的标准Java接口可以与许多其他类重用,因此非常灵活。
Some often used standard java classes that take a CharSequence
as parameter 有些人经常使用标准的java类,它将CharSequence
作为参数
String.contains(CharSequence s)
String.contentEquals(CharSequence cs)
String.replace(CharSequence target, CharSequence replacement)
Appendable.append(CharSequence csq)
StringBuffer.append(CharSequence s)
StringBuilder.append(CharSequence s)
See the full list here . 请在此处查看完整列表。
Use the code above and try this to see how flexibe the decorator is. 使用上面的代码并尝试这个来看看装饰器是如何flexibe的。
public static void main(String[] args) {
String[][] array2d = createArray();
CharSequence charSequnce = new Array2DColumnCharSequnce(array2d, 0);
boolean contentEquals = "Next Next ".contentEquals(charSequnce);
System.out.println(contentEquals);
CharSequence column1CharSequnce = new Array2DColumnCharSequnce(array2d, 1);
String replaced = "I want to say Next Next ".replace(charSequnce, column1CharSequnce);
System.out.println(replaced);
}
will output 将输出
true
I want to say HelloWorld
Finally everyone has to decide what he/she wants and what fits the situation. 最后,每个人都必须决定他/她想要什么以及适合的情况。 I prefer implementations that give me more options if I can get them "almost" for free. 如果我可以免费“几乎”获得它们,我更喜欢为我提供更多选项的实现。
It is similar to search a subString in a String. 它类似于在String中搜索subString。
eg 例如
A B C D N E X T J H J N E N E X T O
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
So the answer should be [4-7]
and [13-16]
. 所以答案应该是[4-7]
和[13-16]
。
public static List<Integer> findIndexes(String source, String toFind){
List<Integer> list = new LinkedList<Integer>();//it will return the starting indexes of the found substring, we can easily find the end e=index by adding the length of the other.
int start = 0;
while(start < source.length()){
if(source.charAt(start)==toFind.charAt(0)){//if the char is same then find whether the whole toFind string is present or not.
if(isMatch(source, toFind, start)){//if it is found than increment the source pointer to the end after the toFind string
list.add(start);
start = start+toFind.length();
continue;
}
}
start++;
}
return list;
}
private static boolean isMatch(String s1, String s2, int srcIndex){
int desIndex = 0;
while(desIndex<s2.length() && s1.charAt(srcIndex)==s2.charAt(desIndex)){
srcIndex++;
desIndex++;
}
if(desIndex==s2.length()){
return true;
}
return false;
}
And sample driver program: 示例驱动程序:
public static void main(String[] args) {
String s1="abcdnextponexnextpour";
String s2 = "next";
List<Integer> list = findIndexes(s1, s2);
for(int i : list){
System.out.println(i);
}
}
It will output the indexes: 它将输出索引:
4
13
ie you can add the length of the toFind
String to calculate the last index. 即你可以添加toFind
String的长度来计算最后一个索引。
I would implement search
as follows - 我会按如下方式实施search
-
public static List<Interval> search(
String searchText, String[][] data) {
List<Interval> al = new ArrayList<>();
if (searchText != null) {
searchText = searchText.trim().toUpperCase();
char[] toMatch = searchText.toCharArray();
for (int i = 0; i < data.length; i++) {
if (data[i] != null && data.length > i
&& data[i].length > 0
&& data[i][0].charAt(0) == toMatch[0]) {
boolean matched = true;
for (int t = 1; t < toMatch.length; t++) {
if (i + t > data.length
|| data[i + t][0].charAt(0) != toMatch[t]) {
i += (t - 1);
matched = false;
break;
}
}
if (matched) {
Interval interval = new Interval();
interval.start = i - 1;
interval.end = interval.start + (toMatch.length - 1);
al.add(interval);
}
}
}
}
return al;
}
And, I would modify Interval
to add a toString()
like this 而且,我会修改Interval
来添加像这样的toString()
public String toString() {
return String.valueOf(start) + "-" + end;
}
Finally, to test it I would use this main method. 最后,为了测试它,我将使用这个主要方法。
public static void main(String[] args) {
String[][] test = { { "N" }, { "A" }, { "N" },
{ "A" }, { "T" }, { "A" }, { "N" }, { "E" },
{ "X" }, { "T" }, { "E" }, { "R" }, { "N" },
{ "B" }, { "N" }, { "E" }, { "X" }, { "T" } };
List<Interval> al = search("next", test);
for (Interval i : al) {
System.out.println(i);
}
}
And I did receive this output - 我确实收到了这个输出 -
5-8
13-16
This is your solution: 这是你的解决方案:
void main(String a[][],String k){
String m="";
for(int i=0;i<a.length;i++)
m+=a[i][0];
int n=0,x;
while(n<m.length()){
n=m.indexOf(k,n);
x=n+k.length();
System.out.println(n+"-"+x);
n=x;
}
}
void main(String a[][],char k){
for(int i=0;i <a.length;i++)
if(a[i][0]==k)System.out.println(i);
}
it extracts the first strings of the dda and searches it. 它提取dda的第一个字符串并进行搜索。 you may generate the value n and x as class interval and include it in list. 您可以生成值n和x作为类间隔并将其包含在列表中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.