Executando verificação de segurança...
1

Eu achava que o problema era naquela expressão justamente porque a exceção apontava pra lá. Mas fui lendo o código novamente e em algum momento indentifiquei o erro.

Essa parte de usar a classe Arrays foi ótimo, não sabia dessa parte.

Sobre o if, ainda vou preencher o código, é porque tava na linha de raciocínio (bem ruim por enquanto, kkk), já tinha preenchido a condição nele e fui escrevendo.

Na parte do while foi mais no "desespero", fui testando tudo que podia pra ver se conseguia indentificar o problema dessa exceção. Sabia, mas pela inexperiência, meio que em alguns momentos a gente vai tentando kkkkk.

A questão de criar outro array, é porque eu quero trazer os dados para fora, para depois manipular o objeto fora do if. Dentro do if o objeto só existe lá, correto?

No caso do resultado final, o while vai rodar o segundo for que está dentro dele até que complete a quantidades de caracteres determinada e então volta ao primeiro for e ele passa para o índice 1, para iterar a segunda remessa de caracteres e assim vai até que finalize.
Ficando:
quebra[0]: "SERA"
quebra[1]: "QUES"
quebra[2]: "OBRA"
Pelo menos essa foi a intenção, e achei que nessa parte tinha acertado. kkkkk.

Peguei essa questão de outro usuário aqui do TabNews. Ele postou que passaram esse teste prático numa entrevista de emprego para dev Sênior. Ele passou como se fosse um grande desrespeito um teste simples desse para um sênior. Então pensei: Se tão testando esse tipo de coisa nas vagas para sênior e o cara tá "esnobando", então deve ser o mínimo que eu teria que saber fazer.

A problemática é:

É passado uma String, exemplo: "TANTOFAZOTEXTO".
É passado também um varíavel x, que passa a quantidades de quebra de linha.
A String tem que ser dividida por igual entre essas linhas, a sobra, se houver coloca numa outra linha, fora a quantidade x.
A sobra de caracteres deve ser colocada no inicio e no fim da String resultante de forma alternada.
As strings resultantes nas linhas pares devem ser invertidas.
No final formar novamente a String e retornar o valor dela.
*Detalhe, o camarada em questão, tinha 10 minutos pra isso.

Carregando publicação patrocinada...
1

Dentro do if o objeto só existe lá, correto?

Se o problema é esse, basta declarar o array fora do if, não precisa criar outro.


Se for para quebrar a string em partes iguais, basta pegar substrings de tamanho fixo, em vez de pegar um caractere de cada vez. E também dê nomes melhores para as variáveis, porque isso ajuda mais do que parece:

String str = "SERAQUESOBRA";
int partes = 3; // dividir a string em 3 partes iguais
int tamanho = str.length() / partes; // tamanho de cada parte
String[] quebra = new String[partes]; // array com as partes
if (str.length() % partes == 0) {
    for (int i = 0; i < str.length(); i += tamanho) {
        quebra[i / tamanho] = str.substring(i, i + tamanho);
    }
    System.out.println(Arrays.toString(quebra));
} else {
    System.out.printf("Não é possível dividir em %d partes iguais\n", partes);
}

// como eu declarei o array fora do if, consigo usar aqui se for preciso

Assim, o array quebra terá "SERA", "QUES" e "OBRA".


Mas tem uma coisa que não ficou claro no enunciado:

A String tem que ser dividida por igual entre essas linhas, a sobra, se houver coloca numa outra linha, fora a quantidade x.
A sobra de caracteres deve ser colocada no inicio e no fim da String resultante de forma alternada.

Se a string for "TANTOFAZOTEXTO" e x for igual a 3, então teríamos as partes:

  • "TANT"
  • "OFAZ"
  • "OTEX"

E a sobra seria "TO", mas não entendi essa regra de "colocada no inicio e no fim da String resultante de forma alternada". Como ficaria o resultado final?

1

Assim ficou o código:

public static void main(String[] args) {

	String str = "TANTOFAZOTEXTO";
	int quebraLinhas = 3;
	int qtdChar = str.length() / quebraLinhas;
	int resto = str.length() % quebraLinhas;
	String[] stringFinal = new String[quebraLinhas+1];
	int contador = 0;


	if (str.length() % quebraLinhas != 0) {

		contador = verificaPar(quebraLinhas);

		String[] quebra = new String[quebraLinhas+1];
		for (int i = 0; i <= str.length()-resto; i += qtdChar) {
			if (i == str.length() - resto) {
				quebra[i / qtdChar] = str.substring(i, str.length());
			} else {
				quebra[i / qtdChar] = str.substring(i, i + qtdChar);
			}

		}

		if (contador > 0) {
			for (int i = 0; i < contador*2; i += 2) {
				for (int j = qtdChar-1; j >= 0; j--) {
					char temp = quebra[i].charAt(j);						
					quebra[i] += temp;
				}
				quebra[i] = quebra[i].substring(qtdChar, qtdChar*2);
			}
		}
		
		for (int i = 0; i < resto; i++) {
								
				char temp = quebra[quebra.length-1].charAt(i);
				String temp2 = String.valueOf(temp);
				
				if ( i % 2 == 0) {
					temp2 = temp + quebra[0];
					quebra[0] = temp2;
				} else {
					quebra[quebra.length-2] += temp2;
				}
				
		}
		stringFinal = quebra;


	} else if (resto == 0) {

		contador = verificaPar(quebraLinhas);

		String[] quebra = new String[quebraLinhas];
		for (int i = 0; i < str.length(); i += qtdChar) {
			quebra[i / qtdChar] = str.substring(i, i + qtdChar);
		}

		if (contador > 0) {
			for (int i = 0; i < contador*2; i += 2) {
				for (int j = qtdChar-1; j >= 0; j--) {
					char temp = quebra[i].charAt(j);						
					quebra[i] += temp;
				}
				quebra[i] = quebra[i].substring(qtdChar, qtdChar*2);
			}
		}
		stringFinal = quebra;
	}

	String palavraFinal = "";
	for (int i = 0; i < stringFinal.length; i++) {
		String temp = stringFinal[i];
		palavraFinal += temp;
	}
	System.out.println(Arrays.toString(stringFinal));
	System.out.println(palavraFinal);
}

public static int verificaPar(int quebraLinhas) {
	int contador = 0;
	for (int i = 0; i < quebraLinhas; i++) {
		if (i % 2 == 0) {
			contador++;
		}
	}
	return contador;
}
    

Em relação a sobra da String, seria assim:
A primeira letra da sobra colocada no início da nova palavra que foi formada pelo array, e a segunda letra colocada ao final, assim sucessivamente até que se esgote os caracteres da sobra.
Lembrando que também precisa inverter o conteúdo dos índices pares.
Ao final de tudo printar a palavra formada.

Tava quase fumaçando já, quando vejo a tua solução, parece a coisa mais simples do mundo. kkkkk. Não desmerecendo tua lógica, claro, mas quero dizer que conseguiu resolver de forma tão simples enquanto eu tava criando um código monstro.

Gosto de ir pegando esses problemas pra tentar resolver, mesmo com código feio e ineficiente mesmo, mas eu vou tentando e vou aprimorando de acordo com os estudos, pra ir evoluindo.

De qualquer forma, agradeço demais tua atenção. Sei que os programadores tem uma vida bem corrida (pelo menos é o que a maioria fala), e tirar um tempo pra vir aqui ajudar a gente que está engatinhando faz toda diferença.

1

Se eu entendi direito, dá para fazer de forma mais simples:

String str = "TANTOFAZOTEXTO";
int quebraLinhas = 3; // dividir a string em 3 partes iguais
int qtdChar = str.length() / quebraLinhas; // tamanho de cada parte
String[] partes = new String[quebraLinhas]; // array com as partes
String sobra = "";
for (int i = 0; i < str.length(); i += qtdChar) {
    if (i + qtdChar <= str.length()) { // ainda tem caracteres suficientes para ser uma parte
        int indice = i / qtdChar;
        String parte = str.substring(i, i + qtdChar);
        if (indice % 2 == 0) { // índice par, inverte a string
            partes[indice] = new StringBuilder(parte).reverse().toString();
        } else {
            partes[indice] = parte;
        }
    } else { // último pedaço é a sobra
        sobra = str.substring(i);
    }
}

// em vez de concatenar strings, use um StringBuilder para ir montando a string aos poucos
StringBuilder sb = new StringBuilder();
// i é o índice do array de partes, j é o índice da sobra
for (int i = 0, j = 0; i < partes.length; i++) {
    if (i % 2 == 0 && j < sobra.length()) { // índice par e ainda tem caracteres da sobra para usar
        if (j % 2 == 0) { // insere a sobra antes
            sb.append(sobra.charAt(j));
            sb.append(partes[i]);
        } else { // insere a sobra depois
            sb.append(partes[i]);
            sb.append(sobra.charAt(j));
        }
        j++;
    } else { // índice ímpar, ou não tem mais caracteres da sobra
        sb.append(partes[i]);
    }
}
sb.append(sobra); // adicione a sobra também

System.out.println(sb.toString()); // TTNATOFAZXETOOTO
1

Só tem um problema nessa lógica, se alterada a quantidade quebras de linhas, a sobra do índice "par", ficaria no meio da String. Nesse caso, a primeira iteração da sobra "par" fica no índice 2. A variável quebraLinhas sendo 4, seria um problema.

O seu código ficou muito mais show, kkkkk.

Mas fiz as alterações para que fique sempre no final as sobras "pares".

Vê se está correto o código. Ele rodou perfeitamente, mas se está correto no sentido de é a melhor forma.

public static void main(String[] args) {

	String str = "TANTOFAZOTEXTO";
	int quebraLinhas = 4;
	int qtdChar = str.length() / quebraLinhas;
	//int resto = str.length() % quebraLinhas;
	String[] partes = new String[quebraLinhas];
	//int contador = 0;
	String sobra = "";

	//Esse for roda até percorrer toda a String
	//a var "i" incrementa de acordo com a quantidade de caracteres em cada quebra de linha
	for (int i = 0; i < str.length(); i+=qtdChar) {
		if (i + qtdChar <= str.length()) { //Esse if valida se o índice inicial até o final é menor que a quantidade de caracteres que ainda tem
			String parte = str.substring(i, i + qtdChar); //Esse método copia o "pedaço" da String que queremos
			int indice = i / qtdChar; //Essa divisão vai sempre dar o indice na sequencia que precisamos: 0, 1 ,2 ....
			if ( indice % 2 == 0) { //Verifica se é par
				//Instanciamos o objeto parte novamente mas na classe StringBuilder ao invés de String, o método reverse reverteu o pedaço da String
				//e como ele não retorna nada, usamos toString para passar o valor.
				partes[indice] = new StringBuilder(parte).reverse().toString();
			} else {
				partes[indice] = parte;
			}
		} else {
			sobra = str.substring(i); //Passando apenas um índice, esse método pega do índice informado até o fim
									  //sem precisar iterar para conseguir todos ou usar uma lógica para passar o
									  //argumento correto para uma substring com os índices iniciais e finais
		}
		
		
	}
	
	//ao invés de concatenar a String, usar o StringBuilder para construir aos poucos
	//StringBuilder é mais performático
	StringBuilder sb = new StringBuilder();
	StringBuilder sbSobra = new StringBuilder();
	
	for (int i = 0, j = 0; i < partes.length; i++) {
		if (i % 2 == 0 && j < sobra.length()) { //Se o índice for par e ainda houver sobra suficiente
			if (j % 2 == 0) { //Começando com 0 que é par, insere antes, e no próximo que é impar, insere depois e sucessivamente
				sb.append(sobra.charAt(j));
				sb.append(partes[i]);
			} else {
				sb.append(partes[i]);
				sbSobra.append(sobra.charAt(j));
			}
			j++;
		} else { //índice ímpar, acrescenta a sobra depois
			sb.append(partes[i]);
		}
	}
	sb.append(sbSobra);
	System.out.println(sb.toString());

}
    

Esses comentários "óbvios" que coloquei é para eu perder menos tempo tentando ler o código quando quiser revisar alguma coisa. Visto que eu salvo todos os pacotes que crio pra poder consultar depois.