Problem during development of string manipulation program - java

I have this problem where a string, sometimes, will repeat its end and I have to remove this repetition, returning only the main string. For example:
in: sanduichuiche out: sanduiche
in: jabutiti out: jabuti
in: sol out: sol
I'm using Java and the solution I came up with is this:
public static void main(String[] args) throws IOException {
String linha;
while ((linha = in.readLine()) != null) {
String palavra = linha;
palavra = palavra.trim()
.replaceAll("\n","")
.replaceAll("\t","");
String subString;
String subStringEncontrada = "";
int palavraLength = palavra.length();
for (int i = palavraLength-1; i >= 0; i--) {
int diff = palavraLength - i;
subString = palavra.substring(i, palavraLength);
if (i-diff < 0) { break; }
if (palavra.substring(i-diff,i).contains(subString)) {
subStringEncontrada = subString;
}
}
String resultado = palavra.substring( 0, palavraLength-subStringEncontrada.length()).trim();
System.out.println(resultado);
}
out.close();
}
For some reason, when I post it to the code challenge, it says 2 of the tests failed, and I have run out of ideas about what can be wrong.
I appreciate if someone could help me out and say what I am missing on this code.

Probably you're overcomplicating.
I wrote this version in a couple minutes, you can try and see if it works for your test cases.
private static String removeEndRepetition(final String str) {
// We need to remove a possible duplicate part of a string, placed at its end.
// This means the max duplicate length is str.length / 2
for (int i = (int) Math.ceil(str.length() / 2.0); i < str.length(); i++) {
final String possibleDuplicatePart = str.substring(i);
final String precedingPart = str.substring(i - possibleDuplicatePart.length(), i);
if (possibleDuplicatePart.equals(precedingPart)) {
return str.substring(0, i);
}
}
return str;
}
public static void main(final String[] args) {
System.out.println(removeEndRepetition("sanduicheiche"));
System.out.println(removeEndRepetition("jabutiti"));
System.out.println(removeEndRepetition("sol"));
}
Which correctly prints
sanduiche
jabuti
sol
How does it work? Kinda debug with sanduicheiche:
possibleDuplicatePart precedingPart
heiche anduic
eiche duich
iche iche MATCH!

Related

Juint actual and expected the same but test fails

I am trying to learn Junit4 and do tests for some of my code. Basically, I am reversing the string and keeps the special symbols in place. During the testing, I found this fail that I can't understand.
My unit test fails although the actual value and expected are the same.
Thank you in advance!
Error:
org.junit.ComparisonFailure:
Expected :d1cba hgf!e
Actual :d1cba hgf!e
Code
public final class AnagramsMaker {
public static String reverseWord(String stringToReverse) {
char[] stringToChar = stringToReverse.toCharArray();
int arrayStart = 0;
int arrayEnd = stringToChar.length - 1;
while (arrayStart < arrayEnd) {
if (Character.isLetter(stringToChar[arrayStart]) && Character.isLetter(stringToChar[arrayEnd])) {
char temp = stringToChar[arrayStart];
stringToChar[arrayStart] = stringToChar[arrayEnd];
stringToChar[arrayEnd] = temp;
arrayStart++;
arrayEnd--;
}
else if (Character.isLetter(stringToChar[arrayStart]) && !Character.isLetter(stringToChar[arrayEnd])) {
arrayEnd--;
}
else if (!Character.isLetter(stringToChar[arrayStart]) && Character.isLetter(stringToChar[arrayEnd])) {
arrayStart++;
}
else {
arrayStart++;
arrayEnd--;
}
}
return String.valueOf(stringToChar);
}
public static String createAnagram(String inputString) {
String anagram = "";
String [] arr = inputString.split(" ");
for (String s : arr) {
anagram += reverseWord(s) + " ";
}
return anagram;
}
}
Junit:
#Test
public void createAnagram() {
assertEquals("d1cba hgf!e", AnagramsMaker.createAnagram("a1bcd efg!h"));
}
I tried reproducing it and got this: expected: <d1cba hgf!e> but was: <d1cba hgf!e >. Notice the extra space in the end.
There is a bug in createAnagram method. You are adding extra space after every string but for the last iteration, extra space is getting appended in the end that's causing this issue.
As fix, trim the value before returning as shown below
public static String createAnagram(String inputString) {
String anagram = "";
String [] arr = inputString.split(" ");
for (String s : arr) {
anagram += reverseWord(s) + " ";
}
return anagram.trim();
}
If you are comfortable with java8 & streams, better approach would be to use Collectors.joining method as shown below
public static String createAnagram(String inputString) {
String[] arr = inputString.split(" ");
return Stream.of(arr)
.map(AnagramsMaker::reverseWord)
.collect(Collectors.joining(" "));
}

Print String words reverse - edge cases

I try to create a function that changes the String from StackOverflow is the best. to best. the is StackOverflow.
I wrote the following function, but can't seem to fix the spaces in the result string. For some reason, I receive best.the is Stackoverflow. There is no space between best. & the, and there is an extra space after StackOverflow.
I could add a variable that represents space and use if's in the edge cases, but I believe that there is a better way to do so.
Could anyone help me figure this out?
public static void main(String[] args) {
String str = "Stackoverflow is the best.";
String result = change(str);
System.out.println(result);
}
private static String change(String str) {
String result = "";
int i1 = str.length()-1;
int i2 = str.length();
for (i1 = str.length(); i1 >= 0; i1--) {
if (i1 ==0 || str.charAt(i1-1) == ' ') {
result = result.concat(str.substring(i1, i2));
i2 = i1;
}
}
return result;
}
One way i could think of without using if's is :
String line = "Stackoverflow is the best.";
String delimeter = " ";
final String[] words = line.split(delimeter);
String reversedLine = "";
for(int i = words.length - 1; i >= 0; i--) {
reversedLine += words[i] + delimeter;
}
// remove the delimeter present at last of line
reversedLine = reversedLine.substring(0, reversedLine.length() - 1);
System.out.println(reversedLine);
To generate the output as you have mentioned, I would approach a problem in this way:
class Solution {
public static void main(String[] args) {
String str = "StackOverflow is the best.";
String[] arr = str.split(" ");
System.out.print(arr[arr.length-1]);
for(int i = arr.length - 2; i >= 0; i--){
System.out.print(" "+arr[i]);
}
}
}
The only reason to your problem is that you haven't added the space after the '.'
Try using String str = "Stackoverflow is the best. ";
Hope it helped... :)

Java permutation of String array

I am trying to find all possible options of combining a string array with two elements. Let's say, the array has two elements {"we","are"}. The output should be:"we" "are" "we are" "are we"
I could manage, with some search, to put together this code:
public class Main {
public static void main(String[] args) {
String[] strings = {"we", "are"};
final int maxbit = 1 << strings.length;
for (int p = 0; p < maxbit; p++) {
String finalString = "";
for (int i = 0; i < strings.length; i++) {
if ((1 << i & p) > 0) {
finalString += strings[i] + " ";
}
}
System.out.println(finalString);
}
}
My problem is, that I am missing one solution, the output is following: "we" "are" "we are".
So I am missing the "are we" option, would I need to use recursion to solve this problem or can this code be modified to show the remaining option?
UPDATE: solution found with the help of answers
public static void main(String[] args) {
String[] test = { "are", "we"};
language(test.length, test, "");
}
private static void language(final int n, final String[] syllables, final String currentWord) { // example of N = 3
if (n == 0) {
System.out.println(currentWord);
} else {
for (int i = 0; i < syllables.length; i++) {
if (currentWord.equals(syllables[i])){
language(n - 1, syllables, "" + syllables[i]);
}else{
language(n - 1, syllables, currentWord + syllables[i]);
}
}
}
}
Another example
import java.util.Arrays;
public class HelloWorld{
public static void main(String[] args) {
String[] strings = {"we", "are"};
String str = Arrays.toString(strings);
System.out.println("Java String array to String = "+str.replace(",","").replace("[","").replace("]",""));
}
}
I looked over it for a while, and found 2 ways to make it based on your code:
this will print out every permutation once, and DOESN'T have to include all the words:
public static void recPerm(String... input) {
recHelper(input, input.length, "");
}
private static void recHelper(String[] input, int length, String currentWord) {
if (currentWord != "")
System.out.println(currentWord);
for (int i = 0; i < input.length; i++) {
if (!currentWord.contains(input[i]))
recHelper(input, length - 1, currentWord + input[i]);
}
}
this will print out every permutation once, and DOES have to include all the words:
public static void maxRecPerm(String... input) {
maxRecHelper(input, input.length, "");
}
private static void maxRecHelper(String[] input, int length, String currentWord) {
if (length == 0)
System.out.println(currentWord);
for (int i = 0; i < input.length; i++) {
if (!currentWord.contains(input[i]))
maxRecHelper(input, length - 1, currentWord + input[i]);
}
}

Java: Return an int out of a var, containing letters and figures

i hope someone can help me, i have the following problem.
I have a variable that looks like this:
var a = "01VENT000KRV010WFEVVV055";
I would like to either:
have the last 3 figures of the variable (e.g. 055) as an int
or remove ALL non-figures out of the variable (e.g. 01000010055) as an int
My idea was that:
int sub = Integer.parseInt(a.substring(a.length-3));
or:
int sub = Integer.parseInt(a.replaceAll("[\\D]", ""));
That didnt work, so i would really appreciate if someone could help me here
Thanks
Note all methods can potentially return an empty string.
public static void main(String[] args) {
// TODO code application logic here
String a = "01VENT000KRV010WFEVVV055";
System.out.println(removeChars(a));
System.out.println(removeDigits(a));
System.out.println(getLastThreeChars(a));
}
//This method removes Characters from a string and returns a String of numbers
static String removeChars(String t)
{
String tempString = "";
for(int i = 0; i < t.length(); i++)
{
if(Character.isDigit(t.charAt(i)))
{
tempString += t.charAt(i);
}
}
return tempString;
}
//This method removes Digits from a string and returns only characters
static String removeDigits(String t)
{
String tempString = "";
for(int i = 0; i < t.length(); i++)
{
if(Character.isAlphabetic(t.charAt(i)))
{
tempString += t.charAt(i);
}
}
return tempString;
}
//This methods prints the last 3 char of a string
static String getLastThreeChars(String t)
{
StringBuilder tempString = new StringBuilder();
for(int i = t.length() - 1; i > t.length() - 1 - 3; i--)
{
tempString.append(t.charAt(i));
}
return tempString.reverse().toString();
}

Split a String into number of Characters desired by the user

I want to split a String into n number of characters.
Consider input to be "Example-for-my-Question". Now if I want to split into n=3 characters, output should be "Exa, mpl, e-f, or-, my-, Que, sti, on" and suppose n=4, output should be "Exam, ple-, for-, my-Q, uest, ion" How can you modify the program below without using POSIX.
import java.util.Scanner;
public class SplitString {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter a String; ");
String inputString = in.nextLine();
System.out.println("How many characters do you want to split into ?");
int n = in.nextInt();
String[] array = inputString.split(" ", n);
System.out.println("Number of words: " + array.length);
for (String arr : array)
System.out.println(arr);
}
}
The simple way to do this is to use String.substring(...) repeatedly to trim N characters off the front of your string ... in a loop.
But if you really want to do this using String.split(...), then I think that the separator regex needs to be a positive look-behind that matches N characters. (It is obscure, and inefficient ... but if regexes are your universal tool ...)
You can use substring for this task.
String sp="StackOverFlow";
int NoOfChars=3;
for(int i=0;i<sp.length();i+=NoOfChars)
{
if(i+NoOfChars<=sp.length())
System.out.println(sp.substring(i,i+NoOfChars));
//Instead add in String ArrayList
else
System.out.println(sp.substring(i));
}
OUTPUT
Sta
ckO
ver
Flo
w
NOTE:Better to use trim() to remove leading or trailing spces
This works for me. In addition to splitting into known lengths, it checks for a null or "too small of a" source string, etc. If a null string is supplied, then a null is returned. If the source string is smaller than the requested split length, then the source string is simply returned.
public static void main (String[] args) throws java.lang.Exception
{
// Three test cases...
String pieces[] = SplitString("Example-for-my-Question", 3);
//String pieces[] = SplitString("Ex", 3);
//String pieces[] = SplitString(null, 3);
if (null != pieces)
{
for (int i = 0; i < pieces.length; i++)
{
System.out.println(pieces[i]);
}
}
}
private static String[] SplitString(String source, int size)
{
String result[] = null;
if (null != source && source.length() > size)
{
int numberOfElements = source.length() / size;
int modulo = source.length() % size;
if (modulo > 0)
{
numberOfElements++;
}
result = new String[numberOfElements];
for (int i = 0; i < numberOfElements; i++)
{
if (numberOfElements - 1 != i)
{
result[i] = source.substring(i * size, (i * size) + size);
}
else
{
result[numberOfElements - 1] = source.substring(i * size, (i * size) + modulo);
}
}
}
else if (null != source)
{
result = new String[1];
result[0] = source;
}
return result;
}
Please try the following program, but here you have to give input to "N" inside the program itself
class Main {
public static void main(String[] args) {
int N = 5;
String text = "aaaaabbbbbccccceeeeefff";
String[] tokens = text.split("(?<=\\G.{" + N + "})");
for(String t : tokens) {
System.out.println(t);
}
}
}

Categories