How can I make this more elegant and applicable to any String? - string

public class JavaIntern{
public static void main(String []args){
String str = "JavaIntern"; //hardcoded, but not the problem
char[] s = str.toCharArray();
String result = new String (s,0,1); //this is where the dilemma begins
System.out.println(result);
String result1 = new String (s,0,2);
System.out.println(result1);
String result2 = new String (s,0,3);
System.out.println(result2);
String result3 = new String (s,0,4);
System.out.println(result3);
String result4 = new String (s,0,5);
System.out.println(result4);
String result5 = new String (s,0,6);
System.out.println(result5);
String result6 = new String (s,0,7);
System.out.println(result6);
String result7 = new String (s,0,8);
System.out.println(result7);
String result8 = new String (s,0,9);
System.out.println(result8);
String result9 = new String (s,0,10);
System.out.println(result9); //and this is where it ends... how can I get rid of this?
}
}
//but still get this:
J
Ja
Jav
Java
JavaI
JavaIn
JavaInt
JavaInte
JavaInter
JavaIntern

I guess you want to improve the code and also don't depend on the length of the string.
What about something like this?
public class JavaIntern{
public static void main(String []args){
String str = "JavaIntern"; //hardcoded, but not the problem
String substring = "";
for (char ch: str.toCharArray()) {
substring += ch;
System.out.println(substring);
}
}
}
This will also print:
J
Ja
Jav
Java
JavaI
JavaIn
JavaInt
JavaInte
JavaInter
JavaIntern
The loop gets one character of the string at a time and concatenates it to the substring before printing it.

Im assuming you want to be able to print out one letter more each time.
To do this we use a for loop, and this way it is fairly simple.
public class MainClass {
public static void main(String[] args) {
String str = "JavaIntern";
for (int i = 1; i <= str.length(); i++) {
System.out.println(str.substring(0, i));
}
}
}
We set i to 0 in the loop, keep iterating while i less than or equal to the length of the string, and each time we iterate, add one to i.
We use the substring method to split the string from the first letter, to i.

Related

How to find missing character in the second string when we compare two strings? - Coding Question

If String a = "abbc" and String b="abc", we have to print that character 'b' is missing in the second string.
I want to do it by using Java. I am able to do it when String 2 has a character not present in String 1 when s1=abc and s2=abk but not when characters are same in both strings like the one I have mentioned in the question.
public class Program
{
public static void main(String[] args) {
String str1 = "abbc";
String str2 = "abc";
char first[] = str1.toCharArray();
char second[] = str2.toCharArray();
HashMap <Character, Integer> map1 = new HashMap<Character,Integer>();
for(char a: first){
if(!map1.containsKey(a)){
map1.put(a,1);
}else{
map1.put(a,map1.get(a)+1);
}
}
System.out.println(map1);
HashMap <Character, Integer> map2 = new HashMap<Character,Integer>();
for(char b: second){
if(!map2.containsKey(b)){
map2.put(b,1);
}else{
map2.put(b,map2.get(b)+1);
}
}
System.out.println(map2);
}
}
I have two hashmaps here one for the longer string and one for the shorter string, map1 {a=1,b=2,c=1} and map2 {a=1,b=1,c=1}. What should I do after this?
Let assume that we have two strings a and b.
(optional) Compare lengths to find longer one.
Iterate over them char by char and compare letters at same index.
If both letters are the same, ignore it. If different, add letter from longer string to result and increment index of the longer string by 1.
What's left in longer string is your result.
Pseudocode:
const a = "aabbccc"
const b = "aabcc"
let res = ""
for (let i = 0, j = 0; i <= a.length; i++, j++) {
if (a[i] !== b[j]) {
res += a[i]
i++
}
}
console.log(res)
More modern and elegant way using high order functions:
const a = "aabbccc"
const b = "aabcc"
const res = [...a].reduce((r, e, i) => e === b[i - r.length] ? r : r + e, "")
console.log(res)

How to collect a string to a stack of characters in Java 8? [duplicate]

I would like to convert the string containing abc to a list of characters and a hashset of characters. How can I do that in Java ?
List<Character> charList = new ArrayList<Character>("abc".toCharArray());
In Java8 you can use streams I suppose.
List of Character objects:
List<Character> chars = str.chars()
.mapToObj(e->(char)e).collect(Collectors.toList());
And set could be obtained in a similar way:
Set<Character> charsSet = str.chars()
.mapToObj(e->(char)e).collect(Collectors.toSet());
You will have to either use a loop, or create a collection wrapper like Arrays.asList which works on primitive char arrays (or directly on strings).
List<Character> list = new ArrayList<Character>();
Set<Character> unique = new HashSet<Character>();
for(char c : "abc".toCharArray()) {
list.add(c);
unique.add(c);
}
Here is an Arrays.asList like wrapper for strings:
public List<Character> asList(final String string) {
return new AbstractList<Character>() {
public int size() { return string.length(); }
public Character get(int index) { return string.charAt(index); }
};
}
This one is an immutable list, though. If you want a mutable list, use this with a char[]:
public List<Character> asList(final char[] string) {
return new AbstractList<Character>() {
public int size() { return string.length; }
public Character get(int index) { return string[index]; }
public Character set(int index, Character newVal) {
char old = string[index];
string[index] = newVal;
return old;
}
};
}
Analogous to this you can implement this for the other primitive types.
Note that using this normally is not recommended, since for every access you
would do a boxing and unboxing operation.
The Guava library contains similar List wrapper methods for several primitive array classes, like Chars.asList, and a wrapper for String in Lists.charactersOf(String).
The lack of a good way to convert between a primitive array and a collection of its corresponding wrapper type is solved by some third party libraries. Guava, a very common one, has a convenience method to do the conversion:
List<Character> characterList = Chars.asList("abc".toCharArray());
Set<Character> characterSet = new HashSet<Character>(characterList);
Use a Java 8 Stream.
myString.chars().mapToObj(i -> (char) i).collect(Collectors.toList());
Breakdown:
myString
.chars() // Convert to an IntStream
.mapToObj(i -> (char) i) // Convert int to char, which gets boxed to Character
.collect(Collectors.toList()); // Collect in a List<Character>
(I have absolutely no idea why String#chars() returns an IntStream.)
The most straightforward way is to use a for loop to add elements to a new List:
String abc = "abc";
List<Character> charList = new ArrayList<Character>();
for (char c : abc.toCharArray()) {
charList.add(c);
}
Similarly, for a Set:
String abc = "abc";
Set<Character> charSet = new HashSet<Character>();
for (char c : abc.toCharArray()) {
charSet.add(c);
}
List<String> result = Arrays.asList("abc".split(""));
Create an empty list of Character and then make a loop to get every character from the array and put them in the list one by one.
List<Character> characterList = new ArrayList<Character>();
char arrayChar[] = abc.toCharArray();
for (char aChar : arrayChar)
{
characterList.add(aChar); // autoboxing
}
You can do this without boxing if you use Eclipse Collections:
CharAdapter abc = Strings.asChars("abc");
CharList list = abc.toList();
CharSet set = abc.toSet();
CharBag bag = abc.toBag();
Because CharAdapter is an ImmutableCharList, calling collect on it will return an ImmutableList.
ImmutableList<Character> immutableList = abc.collect(Character::valueOf);
If you want to return a boxed List, Set or Bag of Character, the following will work:
LazyIterable<Character> lazyIterable = abc.asLazy().collect(Character::valueOf);
List<Character> list = lazyIterable.toList();
Set<Character> set = lazyIterable.toSet();
Bag<Character> set = lazyIterable.toBag();
Note: I am a committer for Eclipse Collections.
IntStream can be used to access each character and add them to the list.
String str = "abc";
List<Character> charList = new ArrayList<>();
IntStream.range(0,str.length()).forEach(i -> charList.add(str.charAt(i)));
Using Java 8 - Stream Funtion:
Converting A String into Character List:
ArrayList<Character> characterList = givenStringVariable
.chars()
.mapToObj(c-> (char)c)
.collect(collectors.toList());
Converting A Character List into String:
String givenStringVariable = characterList
.stream()
.map(String::valueOf)
.collect(Collectors.joining())
To get a list of Characters / Strings -
List<String> stringsOfCharacters = string.chars().
mapToObj(i -> (char)i).
map(c -> c.toString()).
collect(Collectors.toList());

Why do I keep receiving a java.lang.StringIndexOutOfBoundsException

I am trying to write a program that takes a string and removes all instances of another string from it. For example: ("Remove them all!", "em") would print "Rove th all!". However, when I do run this, it give me java.lang.StringIndexOutOfBoundsException.
public class LabFive {
public static String removeAll(String oldPhrase, String removal){
String newPhrase = "";
for(int i = 0; i <= oldPhrase.length(); i++){
if(oldPhrase.substring(i, (removal.length() + i)) == removal)
newPhrase = newPhrase + oldPhrase.substring((removal.length() + 2 + i), oldPhrase.length());
}
return(newPhrase);
}
public static void main(String[] args) {
System.out.println(removeAll("AaAaAa", "a"));
}
}
The easiest way to explain the java.lang.StringIndexOutOfBoundsException is in your loop:
for(int i = 0; i <= oldPhrase.length(); i++){...}
since i is going to be equal to oldPhrase.length() you have a problem with getting the substring:
oldPhrase.substring(i, (removal.length() + i))
so you end up with eventually
oldPhrase.substring(oldPhrase.length(), (removal.length() + oldPhrase.length()))
This is a problem because the highest index in a string is length - 1 and you're trying to access the index at length.
A brute force way of doing removeAll would be to iterate over your string (as you did) and just check, for each character at i, if removal starts there and then the string you want to return would be
sub(0,i) + removeAll(the rest off your string starting at i+removal.length)
public static String removeAll(String oldPhrase,String removal) {
int rem = removal.length();
int n = oldPhrase.length();
// if length of oldPhrase is shorter than removal
// then there nothing you need to remove
if (n < rem) return oldPhrase;
// iterate over your string
for (int i = 0; i <= n - rem; i++) {
int j;
// check if there is a substring, removal, starting at i
for (j = 0; j < rem; j++) {
if (oldPhrase.charAt(i+j) != removal.charAt(j))
break;
}
// if there is...
if (j == rem) {
// return stuff before substring you want to remove +
// removeAll(the stuff after substring you want to remove)
return oldPhrase.substring(0,i) + removeAll(oldPhrase.substring(i+rem,n),removal);
}
}
return oldPhrase;
}
public static void main(String[] args) {
System.out.println(removeAll("AaAaAa", "a"));
}
output:
AAA
Your code seems to have several issues. Firstly, you can't use == to check for string equality, you have to use String.equals() method. Read here.
Secondly, your for loop iterates from 0 to oldPhrase.length() inclusive, but trying to use this length value for index will cause the exception to occur. In java, strings have zero-based index, so index starts from 0 and ends at oldPhrase.length()-1.
Third, your logic seems broken. The substring(int, int) method's parameters are beginIndex and endIndex. So:
newPhrase = newPhrase + oldPhrase.substring((removal.length() + 2 + i), oldPhrase.length());
concatenating part of the oldPhrase till the end to the newPhrase is not going to do what you want.
Here is the way I did it. The idea is simpler, and also clearer. I have added comment to make it clear.
Test the code live on Repl.it
public static String removeAll(String oldPhrase, String removal) {
// if removal is not found return the original string
if(oldPhrase.indexOf(removal) == -1) {
return oldPhrase;
}
int removalLength = removal.length(); // storing the length so as not to call .length() again and again
for(int i = 0; i < oldPhrase.length(); i++) { // note that <= will cause the exception too
int idxOfRemoval = oldPhrase.indexOf(removal);
if(idxOfRemoval == i) { // removal is found at the current index, i.e. at index i
// take substring from beginning to index of removal +
// substring from the end of removal to end of original string
oldPhrase = oldPhrase.substring(0, idxOfRemoval) + oldPhrase.substring(idxOfRemoval+removalLength);
}
}
return(oldPhrase);
}
public static void main(String[] args) {
System.out.println(removeAll("AaAaAa", "a"));
}
Output:
AAA

String Tokenizer requiremen

String str= -PT31121936-1-0069902679870--BLUECH
I want divide the above string by useing string Tokenize
output like this:
amount=" ";
txnNo = PT31121936;
SeqNo = 1;
AccNo = 0069902679870;
Cldflag=" ";
FundOption= BLUECH;
Solution in Java using String split, it would be better than String tokenizer.
There are two solutions
1) This approach is assuming the input string will be always in a specific order.
2) This approach is more dynamic, where we can accommodate change in the order of the input string and also in the number of parameters. My preference would be the second approach.
public class StringSplitExample {
public static void main(String[] args) {
// This solution is based on the order of the input
// is Amount-Txn No-Seq No-Acc No-Cld Flag-Fund Option
String str= "-PT31121936-1-0069902679870--BLUECH";
String[] tokens = str.split("-");
System.out.println("Amount :: "+tokens[0]);
System.out.println("Txn No :: "+tokens[1]);
System.out.println("Seq No :: "+tokens[2]);
System.out.println("Acc No :: "+tokens[3]);
System.out.println("Cld Flag :: "+tokens[4]);
System.out.println("Fund Option :: "+tokens[5]);
// End of First Solution
// The below solution can take any order of input, but we need to provide the order of input
String[] tokensOrder = {"Txn No", "Amount", "Seq No", "Cld Flag", "Acc No", "Fund Option"};
String inputString = "PT31121936--1--0069902679870-BLUECH";
String[] newTokens = inputString.split("-");
// Check whether both arrays are having equal count - To avoid index out of bounds exception
if(newTokens.length == tokensOrder.length) {
for(int i=0; i<tokensOrder.length; i++) {
System.out.println(tokensOrder[i]+" :: "+newTokens[i]);
}
}
}
}
Reference: String Tokenizer vs String split
Scanner vs. StringTokenizer vs. String.Split

When trying to add a space back into a tokenized String, why are two spaces added into my output?

Beginner here. Sorry for the vague title but the code should put my question into perspective.
public static void main(String [] args)
{
String sentence = "hi. how are you! i'm just dandy.";
String tokenSent;
tokenSent = sentenceCapitalizer(sentence);
System.out.println(tokenSent);
}
public static String sentenceCapitalizer(String theSentence)
{
StringTokenizer strTokenizer = new StringTokenizer(theSentence, ".!", true);
String token = null;
String totalToken = "";
String ch = "";
while(strTokenizer.hasMoreTokens())
{
token = strTokenizer.nextToken().trim();
token = token.replace(token.charAt(0), Character.toUpperCase(token.charAt(0)));
StringBuilder str = new StringBuilder(token);
str.append(" ");
totalToken += str;
}
return totalToken;
}
OUTPUT AS IS: Hi . How are you ! I'm just dandy .
I was able to capitalize the first letter of each sentence but I'm wanting the output to keep the same format as the original String. The problem is that it puts a space before and after the ending punctuation. Is there any way to fix this problem using only a StringBuilder and/or StringTokenizer? Thank you for your time.
You can do this.
String delim = ".!";
StringTokenizer strTokenizer = new StringTokenizer(theSentence, delim, true);
Then,
if(delim.contains(token))
str.append(" ");
When you declare new StringTokenizer(theSentence, ".!", true) ,true enables to return delimiter characters also as next token. Since you appending a space to each token, it is normal to get that output.
You can check if the token is a delimiter character, if so, you add the space.
if(token.length() == 1 &&
delims.indexOf(token.charAt(0)) != -1)
str.append(" "); //we just hit the delim char, add space

Resources