简体   繁体   English

Java,编写我自己的拆分字符串方法

[英]Java, writing my own split string method

I need to be able to write my own split string method so that input like我需要能够编写自己的拆分字符串方法,以便输入像

String[] test1 = mySplit("ab#cd#efg#", "#");
System.out.println(Arrays.toString(test1));

will print [ab, #, cd, #, efg, #] to the console.[ab, #, cd, #, efg, #]打印到控制台。 So far I've got it to split like that but my way leaves awkward spaces where 2 delimiters are in a row, or a delimiter is at the start of the input.到目前为止,我已经把它拆分成这样,但我的方式留下了尴尬的空间,其中 2 个分隔符排成一行,或者分隔符位于输入的开头。

public static String[] mySplit(String str, String regex)
{
    String[] storeSplit = new String[str.length()];
    char compare1, compare2;
    int counter = 0;

    //Initializes all the string[] values to "" so when the string
    //and char concatonates, 'null' doesn't appear.
    for(int i=0; i<str.length(); i++) {
        storeSplit[i] = "";
    }

    //Puts the str values into the split array and concatonates until
    //a delimiter is found, then it moves to the next array index.
    for(int i=0; i<str.length(); i++) {
        compare1 = str.charAt(i);
        compare2 = regex.charAt(0);

            if(!(compare1 == compare2)) {
                storeSplit[counter] += ""+str.charAt(i);
            } else {
                counter++;
                storeSplit[counter] = ""+str.charAt(i);
                counter++;
            }
    }
    return storeSplit;
}

When I use that method in my Test main, I get the output [ab, #, cd, #, efg, #, , , , ].当我在 Test main 中使用该方法时,我得到输出 [ab, #, cd, #, efg, #, , , , ]。 So I'm lost on how to fix the spacing of it all and I'll also need to be able to allow multiple delimiters which my code currently doesn't handle.所以我不知道如何修复所有的间距,而且我还需要能够允许我的代码当前无法处理的多个分隔符。

Also I know this code is really sloppy at the moment, just trying to lay down the concepts before the optimization.我也知道这段代码目前真的很草率,只是试图在优化之前放下概念。

The problem is straightforward, you have one offset walking through finding new matches (pos), and another showing then end of the last place you found a match (start).问题很简单,你有一个偏移量来寻找新的匹配(pos),另一个显示你找到匹配的最后一个地方的结尾(开始)。

public static String[] mySplit(String str, String regex)
{
    Vector<String> result = new Vector<String>;
    int start = 0;
    int pos = str.indexOf(regex);
    while (pos>=start) {
        if (pos>start) {
            result.add(str.substring(start,pos));
        }
        start = pos + regex.length();
        result.add(regex);
        pos = str.indexOf(regex,start); 
    }
    if (start<str.length()) {
        result.add(str.substring(start));
    }
    String[] array = result.toArray(new String[0]);
    return array;
}

This avoid extra looping and copies each character only once.这避免了额外的循环并且每个字符只复制一次。 Actually, because of the way that substring works, no characters are ever copied, only small string objects are created pointing to the original character buffer.实际上,由于子字符串的工作方式,不会复制任何字符,只会创建指向原始字符缓冲区的小字符串对象。 No concatenation of strings is done at all, which is an important consideration.根本不进行字符串的串联,这是一个重要的考虑因素。

I think your problem is that you are allocating storeSplit[] with a length that is longer than you need.我认为您的问题是您分配的 storeSplit[] 的长度比您需要的要长。 If you are allowed to use ArrayList, use that to accumulate your results (and use the ArrayList.toArray() method to get the final return value for your function).如果允许您使用 ArrayList,请使用它来累积结果(并使用 ArrayList.toArray() 方法获取函数的最终返回值)。

If you can't use ArrayList, then you will need to truncate your array before returning it (your counter variable will be of use in determining the correct length).如果您不能使用 ArrayList,那么您将需要在返回数组之前截断它(您的计数器变量将用于确定正确的长度)。 To do that, you will need to allocate an array of correct length, then use System.arraycopy to populate it.为此,您需要分配一个正确长度的数组,然后使用 System.arraycopy 来填充它。 Simpler to use ArrayList, but I don't know the exact requirements of your assignment.使用 ArrayList 更简单,但我不知道您的作业的确切要求。

As pointed out in the comments, the problem is that you are setting your array size to the length of the String.正如评论中指出的,问题在于您将数组大小设置为字符串的长度。 Instead, you want to set it to double the number of delimeters.相反,您希望将其设置为分隔符数量的两倍。 Then, adjust accordingly:然后,相应地调整:

  1. If the first character is a delimiter, subtract one,如果第一个字符分隔符,则减去一个,
  2. If the last character is not a delimiter, add one.如果最后一个字符不是分隔符,则添加一个。
// Calculate number of delimiters in str
int delimiters = str.length() - str.replaceAll(regex, "").length();
// Calculate array size
int arraySize = (delimiters * 2) + (str.startsWith(regex) ? -1 : 0);
arraySize = str.endsWith(regex) ? arraySize : arraySize + 1;
String[] storeSplit = new String[arraySize];

It looks like the spacing problem you've got is because of your storeSplit array being a fixed length.看起来您遇到的间距问题是因为您的 storeSplit 数组的长度是固定的。

Let's say your input string is 5 characters long;假设您的输入字符串长度为 5 个字符; your storeSplit array will have 5 'spaces' in there.您的 storeSplit 数组将有 5 个“空格”。 That input string may only contain one delimiter;该输入字符串只能包含一个分隔符; "ab#ef" for example, creating 3 sub-strings - "ab", "#" and "ef".例如,“ab#ef”,创建 3 个子字符串——“ab”、“#”和“ef”。

To avoid this, create a List instead:为避免这种情况,请改为创建一个 List:

List<String> storeSplit = new ArrayList<String>();

Then, rather than incrementing your counter and dropping your text in, add to the list:然后,不要增加计数器并将文本放入其中,而是添加到列表中:

storeSplit.add(""+str.charAt(i));

Instead of而不是

storeSplit[counter] = ""+str.charAt(i);

Here is what I would do:这是我会做的:

String[] test1 = "ab#cd#efg#".split("#");//splits the string on '#'
String result="";
for(String test:test1)//loops through the array
    result+="#"+test;//adds each member to the array putting the '#' in front of each one
System.out.println(result.substring(1));//prints out the string minus the first char, which is a '#'

I hope this helps.我希望这会有所帮助。

here is the output of my code simply click on it package demo;这是我的代码的输出,只需单击它包演示;

public class demo8 {

static int count = 0;
static int first = 0;
static int j = 0;

public static void main(String[] args) {

    String s = "ABHINANDAN TEJKUMAR CHOUGULE";
    int size = 0;

    for (int k = 0; k < s.length(); k++) {
        if (s.charAt(k) == ' ') {
            size++;
        }

    }

    String[] last = new String[size + 1];

    for (int i = 0; i < s.length(); i++) {
        int temp = s.length();

        if (i == s.length() - 1) {
            last[j] = s.substring(first, i + 1);
        }

        if (s.charAt(i) == ' ') {
            last[j] = s.substring(first, i);
            j++;
            first = i + 1;

        }

    }
    for (String s1 : last) {
        System.out.println(s1);
    }
[I tested my code and output is also attached with it ...!][1]}}

I have used recursion to solve it.我已经使用递归来解决它。

static void splitMethod(String str, char splitChar, ArrayList<String> list) {
        String restOfTheStr = null;
        StringBuffer strBufWord = new StringBuffer();
        int pos = str.indexOf(splitChar);
        if(pos>=0) {
            for(int i = 0; i<pos; i++) {
                strBufWord.append(str.charAt(i));
            }
            String word = strBufWord.toString();
            list.add(word);
            restOfTheStr = str.substring(pos+1);//As substring includes the 
            //splitChar, we need to do pos + 1
            splitMethod(restOfTheStr, splitChar, list);
        }
        if(pos == -1) {
            list.add(str);
            return;
        }

    }

Use:使用:

ArrayList<String> list= new ArrayList<String>();//in this list
    //the words will be stored
    String str = "My name is Somenath";
    splitMethod(str,' ', list );

Below is the method下面是方法

public static List<String> split(String str, String demarcation) {
    ArrayList<String> words = new ArrayList<>();
    int startIndex = 0, endIndex;

    endIndex = str.indexOf(demarcation, startIndex);

    while (endIndex != -1) {
        String parts = str.substring(startIndex, endIndex);

        words.add(parts);

        startIndex = endIndex + 1;
        endIndex = str.indexOf(demarcation, startIndex);

    }

    // For the last words
    String parts = str.substring(startIndex);

    words.add(parts);
    return words;
}
    public List<String> split(String str , String regex) {
    char c ;
    int count=0;
    int len = regex.length();
    String temp;
    List<String> result = new ArrayList<>();
    for(int i=0;i<str.length();i++) {
        //System.out.println(str.substring(i, i+len-1));
        temp = str.substring(i, i+len>str.length()?str.length():i+len);
        if(temp.compareTo(regex) == 0) {
            result.add(str.substring(count , i));
            count = i+len;
        }
    }
    result.add(str.substring(count, str.length()));
    return result;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM