我有一个JTextArea,用户可以使用特殊语法创建区域。我正在寻找一些最佳方式的帮助(使用线性时间算法最有效)来确定当前位置是否在非重叠区域之一。
假设我有以下内容来确定用户定义的区域(我在开始时使用正则表达式扫描文档以确定区域):
REGION START = 0, END = 20
REGION START = 21, END = 24
REGION START = 34, END = 40
我不关心用户所在的区域,我只需要确定它们是否位于某个区域内,给定位置X.我可以将这些区域存储为数组并遍历条目,直到找到一个匹配的,但这不是线性时间,如果它与一个区域不匹配则需要更长的时间。
使用算法或以某种方式存储数据有更简单的方法吗?
答案 0 :(得分:1)
答案 1 :(得分:1)
实际上你提议的算法确实是线性的。这是另一个,有点复杂,但更快:
关于二进制索引树:http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees
还有一些代码:
public class BIT {
// AddAtPosition: adds at binary indexed tree [bit] the value [v]
// exactly at position [i]. The binary indexed tree has size [size]
public static void AddAtPosition(int [] bit, int size, int i, int v) {
while(i < size) {
bit[i] += v;
i += (i & -i);
}
}
// AddAtInterval: adds at binary indexed tree [bit] the value [v]
// to all position from [lo] to [hi]. The binary indexed tree has size [size]
public static void AddAtInterval(int [] bit, int size, int lo, int hi, int v) {
AddAtPosition(bit, size, lo+1, v);
AddAtPosition(bit, size, hi+2, -v);
}
// QueryAtPosition: returns the value of index [i] at binary indexed tree [bit]
public static int QueryAtPosition(int [] bit, int i) {
int ans = 0;
i++;
while(i > 0) {
ans += bit[i];
i -= (i & -i);
}
return ans;
}
public static void main(String [] args) {
int [] bit = new int[10+1]; // for values from 0-9
AddAtInterval(bit, 11, 0, 5, 1);
AddAtInterval(bit, 11, 4, 7, 1);
for(int i=0; i<=9; ++i) {
System.out.print("Query At position " + i + ": ");
System.out.println(QueryAtPosition(bit, i));
}
}
}
答案 2 :(得分:0)
虽然我喜欢BIT示例,但我想我可能会使用一个更简单的解决方案,我希望与BIT相比没有巨大的性能影响 - 是否存在,考虑到我需要相同长度的数组开始?我已经根据我的JText区域的长度以相同的方式定义了一个数组:
int[] pC = new int[myArea.getText().length()];
然后我搜索我的区域,每当我找到一个区域时,我在数组中将适当的位置设置为1:
for (int i = m.start(); i < m.end(); i++) {
pC[i] = 1;
}
然后我可以使用以下语法对位置Z进行简单检查:
if (pC[Z] == 0) {
// OUTSIDE REGION
}
else {
// INSIDE REGION
}