Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在字符串数组中搜索子字符串并返回多个值的最有效方法?_Java_Arrays_Substring - Fatal编程技术网

Java 在字符串数组中搜索子字符串并返回多个值的最有效方法?

Java 在字符串数组中搜索子字符串并返回多个值的最有效方法?,java,arrays,substring,Java,Arrays,Substring,假设给定的数组包含: 约旦 乔德 安娜 抢劫 罗伯乔德 您希望返回包含Jord(即Jord、Jordan、RobJord)的所有值的数组,执行此操作的最有效方法是什么 我正在使用Java,但是我不允许使用Java.util数组函数。我想到了这种方法: public ArrayList<String> search(String searchString, String[] names) { ArrayList<String> searchList = new Arra

假设给定的数组包含:

约旦

乔德

安娜

抢劫

罗伯乔德

您希望返回包含Jord(即Jord、Jordan、RobJord)的所有值的数组,执行此操作的最有效方法是什么


我正在使用Java,但是我不允许使用Java.util数组函数。

我想到了这种方法:

public ArrayList<String> search(String searchString, String[] names)
{
  ArrayList<String> searchList = new ArrayList<String>();

  for (String name : names)
  {
    if(name.contains(searchString))
    {
      searchList.add(name);
    }
  }

  return searchList;
}

嗯,因为这听起来像是家庭作业,这是你要解决的,但我会考虑这个非常英语的伪代码。它避免使用
java.util.*
(例如ArrayList或Arrays类),只使用基本构造

count=0
对于输入中的每个项目
如果规则匹配
将计数增加1
创建大小计数的输出数组
目标指数=0
对于输入中的每个项目
如果规则匹配
将该项添加到目标索引处的输出数组中,
并将目标指数提高1
返回输出数组
此代码是
O(n)
in,即使它在输入(
n
)中循环两次,因为这是一个常数,而
O(2*n)
2*O(n)
O(n)

现在,常数边界可以稍微减少,而不是只计算第一次传递,也压缩第一次传递的值,然后只将压缩值(小于或等于
n
)复制到一个新的较小数组。它仍然是
O(n)
,但它的挂钟时间可能稍低。。或者,根据微妙的缓存/JIT/数据因素,它的性能可能会更差。哦,现代计算机的有趣的复杂性


没有简单的方法可以提高
O(n)
的“效率”界限,尤其是一次运行就不需要了。

设置所有内容都需要一些代码,这将是一种可怕的风格,但您可以将字符串转换为字符数组,并使用一个int数组来表示“Jord”中字母的ascii值,因此,您可以通过原语而不是对象引用来获得检查的好处。将要检查的字符传递到一个条件块中,该条件块使用

'J','o','r','d'//74111114100

再一次,我只是建议你这么疯狂,因为你太注重效率了。我马上就要说,将所有东西转移到chars所需的时间存在效率缺陷。这种好处在大型处理任务中最为明显,比如在一整本1000页的电子书中检查Jord,因为初始化只发生一次(或者我想是在大数据块中,但无论哪种方式都是有益的)

同样,它需要一些阻碍性能的设置,再加上它很奇怪,但它确实给了您通过原始int进行验证的好处

另一个想法是考虑某些字母的统计数字,然后再加上另一个字母。例如,“J”后面跟着任何元音的可能性非常高,因此“J”后面跟着“o”但仍然不是“Jord”的可能性非常高,因为我们只有5个元音(加上y,那个奇怪的元音…),例如,你可能会得到“Jork”,而你浪费了检查“o”和“r”的时间。因此,在确定“J”的匹配后,最好将扫描器向上移动几个字母(或当前数组索引计数器-无论您以何种方式迭代)以检查“d”。我认为这会提高效率

基本上,我是说,如果你以这样一种方式构造它,它以迭代的方式逐字母检查,第一步是匹配“J”,然后第二步是跳过“o”,而是检查“r”或“d”。或者换句话说,找到一个候选人,并积极地淘汰候选人


< P>编辑:我实际上在步骤2中检查“D”,如果步骤2检查出来,不要考虑“R”直到步骤2,因为这样你的代码会更简单——从开始,移动到结束,然后迭代回到开始+ 1。如果您在第2步中检查“r”,那么第3步和第4步将是曲折的索引以遍历

,谢谢,但不幸的是,我们也不能使用ArrayList。基本上,任何java.util都是被禁止的。@Lecaille:更新了我的答案。你确定有一种方法可以计算一个子串,而不是
o(n)
使你的上述效率实际上
(n*m)
m是搜索子字符串的字符串长度…@FiringSquadWitness如果可以选择固定值
m
(这样它独立于
n
,这样m不会随着n->无穷大而增加),那么它在Big-O中是
C
-常量。
String[] names = {"Jordan", "Jord", "Anna", "Rob", "RobJord"};
String searchString = "Jord";

ArrayList<String> filterList = search(searchString, names);
public String[] search(String searchString, String[] names)
{
  int size = getSize(searchString, names);
  String[] searchList = new String[size];

  int index = 0;
  for (String name : names)
  {
    if(name.contains(searchString))
    {
      searchList[index++] = name;
    }
  }

  return searchList;
}

// Returns appropriate size for the Search List
private int getSize(String searchString, String[] names)
{
  int size = 0;
  for (String name : names)
  {
    if(name.contains(searchString))
    {
      size++;
    }
  }

  return size;
}
//assuming its case sensitive: ascii values for 'J' 'o' 'r' 'd'
int[] charArr = new int[]{74, 111, 114, 100};