Java 从字符串中删除每8个字符

Java 从字符串中删除每8个字符,java,string,Java,String,我有一个字符串,我想迭代并删除每8个字符。我一直在尝试一个模运算,它检查I%8==0。但是,由于我每删除8个字符,字符串的长度就会减少,因此我无法执行该操作 StringBuilder str = "1100110001011011000000000000000000000000000000000000000000000000"; System.out.println(str + " " + str.length()); for (int i = 0; i < str.length();

我有一个字符串,我想迭代并删除每8个字符。我一直在尝试一个模运算,它检查
I%8==0
。但是,由于我每删除8个字符,字符串的长度就会减少,因此我无法执行该操作

StringBuilder str = "1100110001011011000000000000000000000000000000000000000000000000";
System.out.println(str + " " + str.length());

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

    // Every 8th element should be discarded    
    if (i > 7 && i % 8 == 0) {
        str.deleteCharAt(i);
    }
}

System.out.println(str + " " + str.length());
StringBuilder str=“110001011011000000000000000000000000000000”;
System.out.println(str+“”+str.length());
对于(int i=0;i7&&i%8==0){
deleteCharAt str(i);
}
}
System.out.println(str+“”+str.length());

字符串的长度在开头64,在for循环57之后,应该是56。

string
中没有
deleteCharAt
方法,所以我想您的意思是
StringBuilder

只需反转for循环的方向,使其从字符串的末尾开始:

    String str = "11111111811111118";
    StringBuilder builder = new StringBuilder(str);
    System.out.println(str + " " + str.length());

    for (int i = str.length() - 1; i >= 0; i--) {
        // Every 8th element should be discarded

        if (i > 7 && i % 8 == 0) {
            builder.deleteCharAt(i);
        }
    }

    System.out.println(builder+ " " + builder.length());

通过从字符串末尾删除字符,要删除的字符的索引不再随着字符串的移动而改变。

string
中没有
deleteCharAt
方法,所以我想您的意思是
StringBuilder

只需反转for循环的方向,使其从字符串的末尾开始:

    String str = "11111111811111118";
    StringBuilder builder = new StringBuilder(str);
    System.out.println(str + " " + str.length());

    for (int i = str.length() - 1; i >= 0; i--) {
        // Every 8th element should be discarded

        if (i > 7 && i % 8 == 0) {
            builder.deleteCharAt(i);
        }
    }

    System.out.println(builder+ " " + builder.length());

通过从字符串末尾删除字符,要删除的字符的索引不再随着字符串的移动而改变。

为什么不使用正则表达式并用两行代码实现它呢

public static void main(String[] args) {
    String str = "1100110001011011000000000000000000000000000000000000000000000000";
    String replacedStr = str.replaceAll("([01]{7})[01]", "$1");

    System.out.println(str.toString() + " " + str.length());
    System.out.println(replacedStr.toString() + " " + replacedStr.length());
}
这将提供完全正确的输出

1100110001011011000000000000000000000000000000000000000000000000 64
11001100101101000000000000000000000000000000000000000000 56
或者,您也可以像尝试过的那样遵循此传统解决方案。

java中的字符串是不可变的。因此,您应该创建一个StringBuilder对象并继续复制每个字符,除了第8个字符

为了正确计算每8个字符的数量,请从1而不是0开始初始化For循环索引运行,如下面的代码所示,如果(i%8==0),这将在您希望执行的
操作中有效地消除每8个字符。


您可以在此处验证此输出中只有第8个字符消失的位置。

为什么不使用正则表达式并用两行代码实现它,如下所示

public static void main(String[] args) {
    String str = "1100110001011011000000000000000000000000000000000000000000000000";
    String replacedStr = str.replaceAll("([01]{7})[01]", "$1");

    System.out.println(str.toString() + " " + str.length());
    System.out.println(replacedStr.toString() + " " + replacedStr.length());
}
这将提供完全正确的输出

1100110001011011000000000000000000000000000000000000000000000000 64
11001100101101000000000000000000000000000000000000000000 56
或者,您也可以像尝试过的那样遵循此传统解决方案。

java中的字符串是不可变的。因此,您应该创建一个StringBuilder对象并继续复制每个字符,除了第8个字符

为了正确计算每8个字符的数量,请从1而不是0开始初始化For循环索引运行,如下面的代码所示,如果(i%8==0),这将在您希望执行的
操作中有效地消除每8个字符。


您可以在此处验证此输出中每8个字符的位置。

String
没有
deleteCharAt()
方法。如果是,它将返回更新字符串,因为
string
是不可变的,所以代码必须是
str=str.deleteCharAt(i)

您可以使用,因为它确实有一个方法

要删除每8个字符,请从末尾开始。这样索引值就不会受到已删除字符的影响,这是您当前的问题

String str = "1100110001011011000000000000000000000000000000000000000000000000";
System.out.println(str + " " + str.length());

StringBuilder buf = new StringBuilder(str);
for (int i = (buf.length() - 1) / 8 * 8; i >= 0; i -= 8)
    buf.deleteCharAt(i);
str = buf.toString();
System.out.println(str + " " + str.length());
输出

110001011011000000000000000000000000000000000000064
10011001011011000000000000000000000000000000000000000000 56
更新

上述代码删除第1、9、17、。。。字符,即索引0、8、16…处的字符,符合问题中提到的“每8个字符删除一次”和“检查i%8==0”

如果代码应该删除第8、16、24。。。字符,即索引7、15、23等处的字符,然后将
i
的初始化更改如下:

for (int i = (buf.length() - 8) & ~7 | 7; i >= 0; i -= 8)
    buf.deleteCharAt(i);
输出

110001011011000000000000000000000000000000000000000000064
1100110010100000000000000000000000000000000000056

String
没有
deleteCharAt()
方法。如果是,它将返回更新字符串,因为
string
是不可变的,所以代码必须是
str=str.deleteCharAt(i)

您可以使用,因为它确实有一个方法

要删除每8个字符,请从末尾开始。这样索引值就不会受到已删除字符的影响,这是您当前的问题

String str = "1100110001011011000000000000000000000000000000000000000000000000";
System.out.println(str + " " + str.length());

StringBuilder buf = new StringBuilder(str);
for (int i = (buf.length() - 1) / 8 * 8; i >= 0; i -= 8)
    buf.deleteCharAt(i);
str = buf.toString();
System.out.println(str + " " + str.length());
输出

110001011011000000000000000000000000000000000000064
10011001011011000000000000000000000000000000000000000000 56
更新

上述代码删除第1、9、17、。。。字符,即索引0、8、16…处的字符,符合问题中提到的“每8个字符删除一次”和“检查i%8==0”

如果代码应该删除第8、16、24。。。字符,即索引7、15、23等处的字符,然后将
i
的初始化更改如下:

for (int i = (buf.length() - 8) & ~7 | 7; i >= 0; i -= 8)
    buf.deleteCharAt(i);
输出

110001011011000000000000000000000000000000000000000000064
1100110010100000000000000000000000000000000000056

问题是字符串以0开头。因此,第8个元素有索引7,也必须删除,这在循环中是不需要的。我会这样写(但注意这可能不是最优雅的解决方案):


问题是字符串以0开头。因此,第8个元素有索引7,也必须删除,这在循环中是不需要的。我会这样写(但注意这可能不是最优雅的解决方案):


代码的主要问题是在删除字符时没有调整
i

让我们想象一下。要删除以下标记字符(“每8个元素”):

现在我们在
i=7
并删除该字符,但因为您不调整

110011001011011000000000000000000000000000000000000000000000000
       ^       ^       ^       ^       ^       ^       ^       ^
11001100101101100000000000000000000000000000000000000000000000  //i = 15
1100110010110110000000000000000000000000000000000000000000000   //i = 23
110011001011011000000000000000000000000000000000000000000000    //i = 31
11001100101101100000000000000000000000000000000000000000000     //i = 39
1100110010110110000000000000000000000000000000000000000000      //i = 47
110011001011011000000000000000000000000000000000000000000       //i = 55   
       ^       ^       ^       ^       ^       ^       ^       ^
str.substring(0, 7) -> "1100110"
start += 8; -> start = 8; 
str.substring(8, 15) -> "0101101"
start += 8; -> start = 23; 
    String str = "1100110001011011000000000000000000000000000000000000000000000000";

    int length = str.length();
    int start = 0;

    StringBuilder sb = new StringBuilder();

    while((start+7)<length) {
        sb.append(str.substring(start, start+7));
        start += 8;
    }
    if(start<length) {
        sb.append(str.substring(start, length));
    }

    System.out.println(sb + " " + sb.length());
    System.out.println(str + " " + str.length());
11001100101101000000000000000000000000000000000000000000 56
1100110001011011000000000000000000000000000000000000000000000000 64
    String str = "0123456701234567012345670123456701234567012345670123456701234567";
    System.out.println("initial = " + str);

    char[] array = str.toCharArray();
    for (int i = 7; i < array.length; i = i + 8) {
        array[i] = 0;
    }

    str = String.valueOf(array).replace(String.valueOf(Character.toChars(0)), "");
    System.out.println("final   = " + str);
initial = 0123456701234567012345670123456701234567012345670123456701234567
final   = 01234560123456012345601234560123456012345601234560123456
// create target string
String s = Stream.generate(() -> IntStream.range(0, 10))
    .limit(10)
    .map(stream -> stream.mapToObj(Objects::toString).collect(Collectors.joining()))
    .collect(Collectors.joining());

StringBuilder sb = new StringBuilder(s);

// delete first element or not?
boolean removeFirst = false;
IntStream.range(removeFirst ? 0 : 1, s.length())
    .boxed()
    .sorted(Collections.reverseOrder()) // reverse number stream
    .filter(i -> i % 8 == 0) // only keep multiples of 8
    .forEach(sb::deleteCharAt);

System.out.println(s);
System.out.println(sb.toString());