Trouble implementing quicksort recursion in java - java

I'm doing a project for school and I have to test the speeds of binary vs linear searches for a spellcheck implementation. We have to use this certain SpellCheck. The examples given by my professor for binary search using recursion were a few separate snippets of code designed for ints and he wants us to make it work for this implementation with strings. Any help would be appreciated, I am very stuck at the moment. SortedWordList is the class i need help on.
import java.util.Scanner;
public class Spellcheck {
private static WordList listOfWords;// The list of correctly spelled words.
public static void main(String[] args) {
long start = System.nanoTime();
listOfWords = new SortedWordList();
//listOfWords = new WordList();
long end = System.nanoTime();
long WL = (end-start);
//end = 0;
//start = 0;
long SW = 0;
Scanner in = new Scanner(System.in);
while (true) { // Get and process one word from the user.
System.out.println();
System.out.print("Enter a word to be cheched (press return to end): ");
String word = in.nextLine().trim().toLowerCase();
start = System.nanoTime();
if (word.length() == 0)
break;
if (listOfWords.contains(word)) {
System.out.println("'" + word + "' is a legal word.");
}
else {
System.out.println("'" + word + "' is not a legal word.");
System.out.println("If there are similar words, they are shown here:");
trySubstitute(word);
tryInsert(word);
tryDelete(word);
trySwap(word);
tryBreak(word);
end = System.nanoTime();
SW = (end-start);
}
System.out.println();
System.out.printf("Time to create word list: %,d nanoseconds.%n",(WL));
System.out.println();
System.out.printf("Time to test for similar words: %,d nanoseconds.%n",(SW));
System.out.println();
System.out.printf("Time to test total: %,d nanoseconds.%n",(SW + WL));
}
}
private static void trySubstitute(String word) {
for (int i = 0; i < word.length(); i++) {
String before = word.substring(0, i);
String after = word.substring(i+1);
for (char ch = 'a'; ch < 'z'; ch++) {
String newword = before + ch + after;
if (listOfWords.contains(newword))
System.out.println(" " + newword);
}
}
}
private static void tryInsert(String word) {
for (int i = 0; i <= word.length(); i++) {
String before = word.substring(0,i);
String after = word.substring(i);
for (char ch = 'a'; ch < 'z'; ch++) {
String newword = before + ch + after;
if (listOfWords.contains(newword))
System.out.println(" " + newword);
}
}
}
private static void tryDelete(String word) {
for (int i = 0; i < word.length(); i++) {
String before = word.substring(0, i);
String after = word.substring(i+1);
String newword = before + after;
if (listOfWords.contains(newword))
System.out.println(" " + newword);
}
}
private static void trySwap(String word) {
for (int i = 0; i < word.length() - 1; i++) {
String before = word.substring(0, i);
char a = word.charAt(i);
char b = word.charAt(i+1);
String after = word.substring(i+2);
String newword = before + b + a + after;
if (listOfWords.contains(newword))
System.out.println(" " + newword);
}
}
private static void tryBreak(String word) {
for (int i = 1; i < word.length() - 1; i++) {
String before = word.substring(0, i);
String after = word.substring(i);
if (listOfWords.contains(before) && listOfWords.contains(after))
System.out.println(" " + before + " " + after);
}
}
} // end class Spellcheck
`
import java.util.ArrayList;
import java.util.Scanner;
import java.net.URL;
public class WordList {
protected final String[] words; // the list of words
public WordList() {
try {
URL listLocation = WordList.class.getClassLoader().getResource("unsorted_words.txt");
Scanner in = new Scanner( listLocation.openStream() );
ArrayList<String> wordList = new ArrayList<String>();
while (in.hasNextLine())
wordList.add(in.nextLine());
words = wordList.toArray(new String[] {});
in.close();
}
catch (Exception e) {
throw new IllegalStateException("Can't load list of words from file 'unsorted_words.txt'");
}
}
public boolean contains(String lowerCaseWord) {
for (String s : words) {
if (s.equals(lowerCaseWord))
return true;
}
return false;
}
public int size() {
return words.length;
}
public String get(int index) {
return words[index];
}
}
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Scanner;
public class SortedWordList extends WordList {
public String [] words;
public SortedWordList() {
URL listLocation = SortedWordList.class.getClassLoader().getResource("unsorted_words.txt");
Scanner in = null;
try {
in = new Scanner( listLocation.openStream() );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ArrayList<String> wordList = new ArrayList<String>();
while (in.hasNextLine())
wordList.add(in.nextLine());
words = wordList.toArray(new String[] {});
in.close();
}
//public boolean contains(String lowerCaseWord) {
//}
static int binarySearch(String[] A, int loIndex, int hiIndex, String value) {
if (loIndex > hiIndex) {
return -1;
}
else {
int middle = (loIndex + hiIndex) / 2;
if (value == A[middle])
return middle;
else if ((A[middle].compareTo(value)) > 0)
return binarySearch(A, loIndex, middle - 1, value);
else // value must be > A[middle]
return binarySearch(A, middle + 1, hiIndex, value);
}
} // end binarySearch()
static int quicksortStep(String[] A, int lo, int hi) {
String pivot = A[lo]; // Get the pivot value.
while (hi > lo) {
while (hi > lo && ((pivot.compareTo(A[hi])) <= 0)) {
hi--;
}
if (hi == lo)
break;
A[lo] = A[hi];
lo++;
while (hi > lo && ((pivot.compareTo(A[lo])) >= 0)) {
lo++;
}
if (hi == lo)
break;
A[hi] = A[lo];
hi--;
} // end while
A[lo] = pivot;
return lo;
} // end QuicksortStep
static void quicksort(String[] A, int lo, int hi) {
if (hi <= lo) {
return;
}
else {
int pivotPosition = quicksortStep(A, lo, hi);
quicksort(A, lo, pivotPosition - 1);
quicksort(A, pivotPosition + 1, hi);
}
}
}

First, where do you need to call quicksort? Just guessing by the class's name of SortedWordList, it would seem to me that you would need to call this quicksort method inside the SortedWordList's constructor. Right now, the constructor appears to load an unsorted list of words.
If that doesn't solve the problem, I would then also look at your quicksortStep method inside the SortedWordList class again. This quicksortStep method is basically the partition method. (See https://www.programcreek.com/2012/11/quicksort-array-in-java/ for an example). I would try to follow the same code structure in the quicksortStep method as the partition method in the link above, and then modify it for strings, until it is something like:
public static int partition(String[] arr, int start, int end){
String pivot = arr[end];
for(int i=start; i<end; i++){
if((arr[i].compareTo(pivot)) < 0){
String temp= arr[start];
arr[start]=arr[i];
arr[i]=temp;
start++;
}
}
String temp = arr[start];
arr[start] = pivot;
arr[end] = temp;
return start;
}
Feel free to rename methods / variables.

Related

Efficient/Fast way to get permutation of a String in java [duplicate]

What is an elegant way to find all the permutations of a string. E.g. permutation for ba, would be ba and ab, but what about longer string such as abcdefgh? Is there any Java implementation example?
public static void permutation(String str) {
permutation("", str);
}
private static void permutation(String prefix, String str) {
int n = str.length();
if (n == 0) System.out.println(prefix);
else {
for (int i = 0; i < n; i++)
permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
}
}
(via Introduction to Programming in Java)
Use recursion.
Try each of the letters in turn as the first letter and then find all the permutations of the remaining letters using a recursive call.
The base case is when the input is an empty string the only permutation is the empty string.
Here is my solution that is based on the idea of the book "Cracking the Coding Interview" (P54):
/**
* List permutations of a string.
*
* #param s the input string
* #return the list of permutations
*/
public static ArrayList<String> permutation(String s) {
// The result
ArrayList<String> res = new ArrayList<String>();
// If input string's length is 1, return {s}
if (s.length() == 1) {
res.add(s);
} else if (s.length() > 1) {
int lastIndex = s.length() - 1;
// Find out the last character
String last = s.substring(lastIndex);
// Rest of the string
String rest = s.substring(0, lastIndex);
// Perform permutation on the rest string and
// merge with the last character
res = merge(permutation(rest), last);
}
return res;
}
/**
* #param list a result of permutation, e.g. {"ab", "ba"}
* #param c the last character
* #return a merged new list, e.g. {"cab", "acb" ... }
*/
public static ArrayList<String> merge(ArrayList<String> list, String c) {
ArrayList<String> res = new ArrayList<>();
// Loop through all the string in the list
for (String s : list) {
// For each string, insert the last character to all possible positions
// and add them to the new list
for (int i = 0; i <= s.length(); ++i) {
String ps = new StringBuffer(s).insert(i, c).toString();
res.add(ps);
}
}
return res;
}
Running output of string "abcd":
Step 1: Merge [a] and b:
[ba, ab]
Step 2: Merge [ba, ab] and c:
[cba, bca, bac, cab, acb, abc]
Step 3: Merge [cba, bca, bac, cab, acb, abc] and d:
[dcba, cdba, cbda, cbad, dbca, bdca, bcda, bcad, dbac, bdac, badc, bacd, dcab, cdab, cadb, cabd, dacb, adcb, acdb, acbd, dabc, adbc, abdc, abcd]
Of all the solutions given here and in other forums, I liked Mark Byers the most. That description actually made me think and code it myself.
Too bad I cannot voteup his solution as I am newbie.
Anyways here is my implementation of his description
public class PermTest {
public static void main(String[] args) throws Exception {
String str = "abcdef";
StringBuffer strBuf = new StringBuffer(str);
doPerm(strBuf,0);
}
private static void doPerm(StringBuffer str, int index){
if(index == str.length())
System.out.println(str);
else { //recursively solve this by placing all other chars at current first pos
doPerm(str, index+1);
for (int i = index+1; i < str.length(); i++) {//start swapping all other chars with current first char
swap(str,index, i);
doPerm(str, index+1);
swap(str,i, index);//restore back my string buffer
}
}
}
private static void swap(StringBuffer str, int pos1, int pos2){
char t1 = str.charAt(pos1);
str.setCharAt(pos1, str.charAt(pos2));
str.setCharAt(pos2, t1);
}
}
I prefer this solution ahead of the first one in this thread because this solution uses StringBuffer. I wouldn't say my solution doesn't create any temporary string (it actually does in system.out.println where the toString() of StringBuffer is called). But I just feel this is better than the first solution where too many string literals are created. May be some performance guy out there can evalute this in terms of 'memory' (for 'time' it already lags due to that extra 'swap')
A very basic solution in Java is to use recursion + Set ( to avoid repetitions ) if you want to store and return the solution strings :
public static Set<String> generatePerm(String input)
{
Set<String> set = new HashSet<String>();
if (input == "")
return set;
Character a = input.charAt(0);
if (input.length() > 1)
{
input = input.substring(1);
Set<String> permSet = generatePerm(input);
for (String x : permSet)
{
for (int i = 0; i <= x.length(); i++)
{
set.add(x.substring(0, i) + a + x.substring(i));
}
}
}
else
{
set.add(a + "");
}
return set;
}
All the previous contributors have done a great job explaining and providing the code. I thought I should share this approach too because it might help someone too. The solution is based on (heaps' algorithm )
Couple of things:
Notice the last item which is depicted in the excel is just for helping you better visualize the logic. So, the actual values in the last column would be 2,1,0 (if we were to run the code because we are dealing with arrays and arrays start with 0).
The swapping algorithm happens based on even or odd values of current position. It's very self explanatory if you look at where the swap method is getting called.You can see what's going on.
Here is what happens:
public static void main(String[] args) {
String ourword = "abc";
String[] ourArray = ourword.split("");
permute(ourArray, ourArray.length);
}
private static void swap(String[] ourarray, int right, int left) {
String temp = ourarray[right];
ourarray[right] = ourarray[left];
ourarray[left] = temp;
}
public static void permute(String[] ourArray, int currentPosition) {
if (currentPosition == 1) {
System.out.println(Arrays.toString(ourArray));
} else {
for (int i = 0; i < currentPosition; i++) {
// subtract one from the last position (here is where you are
// selecting the the next last item
permute(ourArray, currentPosition - 1);
// if it's odd position
if (currentPosition % 2 == 1) {
swap(ourArray, 0, currentPosition - 1);
} else {
swap(ourArray, i, currentPosition - 1);
}
}
}
}
Let's use input abc as an example.
Start off with just the last element (c) in a set (["c"]), then add the second last element (b) to its front, end and every possible positions in the middle, making it ["bc", "cb"] and then in the same manner it will add the next element from the back (a) to each string in the set making it:
"a" + "bc" = ["abc", "bac", "bca"] and "a" + "cb" = ["acb" ,"cab", "cba"]
Thus entire permutation:
["abc", "bac", "bca","acb" ,"cab", "cba"]
Code:
public class Test
{
static Set<String> permutations;
static Set<String> result = new HashSet<String>();
public static Set<String> permutation(String string) {
permutations = new HashSet<String>();
int n = string.length();
for (int i = n - 1; i >= 0; i--)
{
shuffle(string.charAt(i));
}
return permutations;
}
private static void shuffle(char c) {
if (permutations.size() == 0) {
permutations.add(String.valueOf(c));
} else {
Iterator<String> it = permutations.iterator();
for (int i = 0; i < permutations.size(); i++) {
String temp1;
for (; it.hasNext();) {
temp1 = it.next();
for (int k = 0; k < temp1.length() + 1; k += 1) {
StringBuilder sb = new StringBuilder(temp1);
sb.insert(k, c);
result.add(sb.toString());
}
}
}
permutations = result;
//'result' has to be refreshed so that in next run it doesn't contain stale values.
result = new HashSet<String>();
}
}
public static void main(String[] args) {
Set<String> result = permutation("abc");
System.out.println("\nThere are total of " + result.size() + " permutations:");
Iterator<String> it = result.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
This one is without recursion
public static void permute(String s) {
if(null==s || s.isEmpty()) {
return;
}
// List containing words formed in each iteration
List<String> strings = new LinkedList<String>();
strings.add(String.valueOf(s.charAt(0))); // add the first element to the list
// Temp list that holds the set of strings for
// appending the current character to all position in each word in the original list
List<String> tempList = new LinkedList<String>();
for(int i=1; i< s.length(); i++) {
for(int j=0; j<strings.size(); j++) {
tempList.addAll(merge(s.charAt(i), strings.get(j)));
}
strings.removeAll(strings);
strings.addAll(tempList);
tempList.removeAll(tempList);
}
for(int i=0; i<strings.size(); i++) {
System.out.println(strings.get(i));
}
}
/**
* helper method that appends the given character at each position in the given string
* and returns a set of such modified strings
* - set removes duplicates if any(in case a character is repeated)
*/
private static Set<String> merge(Character c, String s) {
if(s==null || s.isEmpty()) {
return null;
}
int len = s.length();
StringBuilder sb = new StringBuilder();
Set<String> list = new HashSet<String>();
for(int i=0; i<= len; i++) {
sb = new StringBuilder();
sb.append(s.substring(0, i) + c + s.substring(i, len));
list.add(sb.toString());
}
return list;
}
Well here is an elegant, non-recursive, O(n!) solution:
public static StringBuilder[] permutations(String s) {
if (s.length() == 0)
return null;
int length = fact(s.length());
StringBuilder[] sb = new StringBuilder[length];
for (int i = 0; i < length; i++) {
sb[i] = new StringBuilder();
}
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
int times = length / (i + 1);
for (int j = 0; j < times; j++) {
for (int k = 0; k < length / times; k++) {
sb[j * length / times + k].insert(k, ch);
}
}
}
return sb;
}
One of the simple solution could be just keep swapping the characters recursively using two pointers.
public static void main(String[] args)
{
String str="abcdefgh";
perm(str);
}
public static void perm(String str)
{ char[] char_arr=str.toCharArray();
helper(char_arr,0);
}
public static void helper(char[] char_arr, int i)
{
if(i==char_arr.length-1)
{
// print the shuffled string
String str="";
for(int j=0; j<char_arr.length; j++)
{
str=str+char_arr[j];
}
System.out.println(str);
}
else
{
for(int j=i; j<char_arr.length; j++)
{
char tmp = char_arr[i];
char_arr[i] = char_arr[j];
char_arr[j] = tmp;
helper(char_arr,i+1);
char tmp1 = char_arr[i];
char_arr[i] = char_arr[j];
char_arr[j] = tmp1;
}
}
}
python implementation
def getPermutation(s, prefix=''):
if len(s) == 0:
print prefix
for i in range(len(s)):
getPermutation(s[0:i]+s[i+1:len(s)],prefix+s[i] )
getPermutation('abcd','')
This is what I did through basic understanding of Permutations and Recursive function calling. Takes a bit of time but it's done independently.
public class LexicographicPermutations {
public static void main(String[] args) {
// TODO Auto-generated method stub
String s="abc";
List<String>combinations=new ArrayList<String>();
combinations=permutations(s);
Collections.sort(combinations);
System.out.println(combinations);
}
private static List<String> permutations(String s) {
// TODO Auto-generated method stub
List<String>combinations=new ArrayList<String>();
if(s.length()==1){
combinations.add(s);
}
else{
for(int i=0;i<s.length();i++){
List<String>temp=permutations(s.substring(0, i)+s.substring(i+1));
for (String string : temp) {
combinations.add(s.charAt(i)+string);
}
}
}
return combinations;
}}
which generates Output as [abc, acb, bac, bca, cab, cba].
Basic logic behind it is
For each character, consider it as 1st character & find the combinations of remaining characters. e.g. [abc](Combination of abc)->.
a->[bc](a x Combination of (bc))->{abc,acb}
b->[ac](b x Combination of (ac))->{bac,bca}
c->[ab](c x Combination of (ab))->{cab,cba}
And then recursively calling each [bc],[ac] & [ab] independently.
Use recursion.
when the input is an empty string the only permutation is an empty string.Try for each of the letters in the string by making it as the first letter and then find all the permutations of the remaining letters using a recursive call.
import java.util.ArrayList;
import java.util.List;
class Permutation {
private static List<String> permutation(String prefix, String str) {
List<String> permutations = new ArrayList<>();
int n = str.length();
if (n == 0) {
permutations.add(prefix);
} else {
for (int i = 0; i < n; i++) {
permutations.addAll(permutation(prefix + str.charAt(i), str.substring(i + 1, n) + str.substring(0, i)));
}
}
return permutations;
}
public static void main(String[] args) {
List<String> perms = permutation("", "abcd");
String[] array = new String[perms.size()];
for (int i = 0; i < perms.size(); i++) {
array[i] = perms.get(i);
}
int x = array.length;
for (final String anArray : array) {
System.out.println(anArray);
}
}
}
this worked for me..
import java.util.Arrays;
public class StringPermutations{
public static void main(String args[]) {
String inputString = "ABC";
permute(inputString.toCharArray(), 0, inputString.length()-1);
}
public static void permute(char[] ary, int startIndex, int endIndex) {
if(startIndex == endIndex){
System.out.println(String.valueOf(ary));
}else{
for(int i=startIndex;i<=endIndex;i++) {
swap(ary, startIndex, i );
permute(ary, startIndex+1, endIndex);
swap(ary, startIndex, i );
}
}
}
public static void swap(char[] ary, int x, int y) {
char temp = ary[x];
ary[x] = ary[y];
ary[y] = temp;
}
}
Java implementation without recursion
public Set<String> permutate(String s){
Queue<String> permutations = new LinkedList<String>();
Set<String> v = new HashSet<String>();
permutations.add(s);
while(permutations.size()!=0){
String str = permutations.poll();
if(!v.contains(str)){
v.add(str);
for(int i = 0;i<str.length();i++){
String c = String.valueOf(str.charAt(i));
permutations.add(str.substring(i+1) + c + str.substring(0,i));
}
}
}
return v;
}
Let me try to tackle this problem with Kotlin:
fun <T> List<T>.permutations(): List<List<T>> {
//escape case
if (this.isEmpty()) return emptyList()
if (this.size == 1) return listOf(this)
if (this.size == 2) return listOf(listOf(this.first(), this.last()), listOf(this.last(), this.first()))
//recursive case
return this.flatMap { lastItem ->
this.minus(lastItem).permutations().map { it.plus(lastItem) }
}
}
Core concept: Break down long list into smaller list + recursion
Long answer with example list [1, 2, 3, 4]:
Even for a list of 4 it already kinda get's confusing trying to list all the possible permutations in your head, and what we need to do is exactly to avoid that. It is easy for us to understand how to make all permutations of list of size 0, 1, and 2, so all we need to do is break them down to any of those sizes and combine them back up correctly. Imagine a jackpot machine: this algorithm will start spinning from the right to the left, and write down
return empty/list of 1 when list size is 0 or 1
handle when list size is 2 (e.g. [3, 4]), and generate the 2 permutations ([3, 4] & [4, 3])
For each item, mark that as the last in the last, and find all the permutations for the rest of the item in the list. (e.g. put [4] on the table, and throw [1, 2, 3] into permutation again)
Now with all permutation it's children, put itself back to the end of the list (e.g.: [1, 2, 3][,4], [1, 3, 2][,4], [2, 3, 1][, 4], ...)
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
public class hello {
public static void main(String[] args) throws IOException {
hello h = new hello();
h.printcomp();
}
int fact=1;
public void factrec(int a,int k){
if(a>=k)
{fact=fact*k;
k++;
factrec(a,k);
}
else
{System.out.println("The string will have "+fact+" permutations");
}
}
public void printcomp(){
String str;
int k;
Scanner in = new Scanner(System.in);
System.out.println("enter the string whose permutations has to b found");
str=in.next();
k=str.length();
factrec(k,1);
String[] arr =new String[fact];
char[] array = str.toCharArray();
while(p<fact)
printcomprec(k,array,arr);
// if incase u need array containing all the permutation use this
//for(int d=0;d<fact;d++)
//System.out.println(arr[d]);
}
int y=1;
int p = 0;
int g=1;
int z = 0;
public void printcomprec(int k,char array[],String arr[]){
for (int l = 0; l < k; l++) {
for (int b=0;b<k-1;b++){
for (int i=1; i<k-g; i++) {
char temp;
String stri = "";
temp = array[i];
array[i] = array[i + g];
array[i + g] = temp;
for (int j = 0; j < k; j++)
stri += array[j];
arr[z] = stri;
System.out.println(arr[z] + " " + p++);
z++;
}
}
char temp;
temp=array[0];
array[0]=array[y];
array[y]=temp;
if (y >= k-1)
y=y-(k-1);
else
y++;
}
if (g >= k-1)
g=1;
else
g++;
}
}
/** Returns an array list containing all
* permutations of the characters in s. */
public static ArrayList<String> permute(String s) {
ArrayList<String> perms = new ArrayList<>();
int slen = s.length();
if (slen > 0) {
// Add the first character from s to the perms array list.
perms.add(Character.toString(s.charAt(0)));
// Repeat for all additional characters in s.
for (int i = 1; i < slen; ++i) {
// Get the next character from s.
char c = s.charAt(i);
// For each of the strings currently in perms do the following:
int size = perms.size();
for (int j = 0; j < size; ++j) {
// 1. remove the string
String p = perms.remove(0);
int plen = p.length();
// 2. Add plen + 1 new strings to perms. Each new string
// consists of the removed string with the character c
// inserted into it at a unique location.
for (int k = 0; k <= plen; ++k) {
perms.add(p.substring(0, k) + c + p.substring(k));
}
}
}
}
return perms;
}
Here is a straightforward minimalist recursive solution in Java:
public static ArrayList<String> permutations(String s) {
ArrayList<String> out = new ArrayList<String>();
if (s.length() == 1) {
out.add(s);
return out;
}
char first = s.charAt(0);
String rest = s.substring(1);
for (String permutation : permutations(rest)) {
out.addAll(insertAtAllPositions(first, permutation));
}
return out;
}
public static ArrayList<String> insertAtAllPositions(char ch, String s) {
ArrayList<String> out = new ArrayList<String>();
for (int i = 0; i <= s.length(); ++i) {
String inserted = s.substring(0, i) + ch + s.substring(i);
out.add(inserted);
}
return out;
}
We can use factorial to find how many strings started with particular letter.
Example: take the input abcd. (3!) == 6 strings will start with every letter of abcd.
static public int facts(int x){
int sum = 1;
for (int i = 1; i < x; i++) {
sum *= (i+1);
}
return sum;
}
public static void permutation(String str) {
char[] str2 = str.toCharArray();
int n = str2.length;
int permutation = 0;
if (n == 1) {
System.out.println(str2[0]);
} else if (n == 2) {
System.out.println(str2[0] + "" + str2[1]);
System.out.println(str2[1] + "" + str2[0]);
} else {
for (int i = 0; i < n; i++) {
if (true) {
char[] str3 = str.toCharArray();
char temp = str3[i];
str3[i] = str3[0];
str3[0] = temp;
str2 = str3;
}
for (int j = 1, count = 0; count < facts(n-1); j++, count++) {
if (j != n-1) {
char temp1 = str2[j+1];
str2[j+1] = str2[j];
str2[j] = temp1;
} else {
char temp1 = str2[n-1];
str2[n-1] = str2[1];
str2[1] = temp1;
j = 1;
} // end of else block
permutation++;
System.out.print("permutation " + permutation + " is -> ");
for (int k = 0; k < n; k++) {
System.out.print(str2[k]);
} // end of loop k
System.out.println();
} // end of loop j
} // end of loop i
}
}
//insert each character into an arraylist
static ArrayList al = new ArrayList();
private static void findPermutation (String str){
for (int k = 0; k < str.length(); k++) {
addOneChar(str.charAt(k));
}
}
//insert one char into ArrayList
private static void addOneChar(char ch){
String lastPerStr;
String tempStr;
ArrayList locAl = new ArrayList();
for (int i = 0; i < al.size(); i ++ ){
lastPerStr = al.get(i).toString();
//System.out.println("lastPerStr: " + lastPerStr);
for (int j = 0; j <= lastPerStr.length(); j++) {
tempStr = lastPerStr.substring(0,j) + ch +
lastPerStr.substring(j, lastPerStr.length());
locAl.add(tempStr);
//System.out.println("tempStr: " + tempStr);
}
}
if(al.isEmpty()){
al.add(ch);
} else {
al.clear();
al = locAl;
}
}
private static void printArrayList(ArrayList al){
for (int i = 0; i < al.size(); i++) {
System.out.print(al.get(i) + " ");
}
}
//Rotate and create words beginning with all letter possible and push to stack 1
//Read from stack1 and for each word create words with other letters at the next location by rotation and so on
/* eg : man
1. push1 - man, anm, nma
2. pop1 - nma , push2 - nam,nma
pop1 - anm , push2 - amn,anm
pop1 - man , push2 - mna,man
*/
public class StringPermute {
static String str;
static String word;
static int top1 = -1;
static int top2 = -1;
static String[] stringArray1;
static String[] stringArray2;
static int strlength = 0;
public static void main(String[] args) throws IOException {
System.out.println("Enter String : ");
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader bfr = new BufferedReader(isr);
str = bfr.readLine();
word = str;
strlength = str.length();
int n = 1;
for (int i = 1; i <= strlength; i++) {
n = n * i;
}
stringArray1 = new String[n];
stringArray2 = new String[n];
push(word, 1);
doPermute();
display();
}
public static void push(String word, int x) {
if (x == 1)
stringArray1[++top1] = word;
else
stringArray2[++top2] = word;
}
public static String pop(int x) {
if (x == 1)
return stringArray1[top1--];
else
return stringArray2[top2--];
}
public static void doPermute() {
for (int j = strlength; j >= 2; j--)
popper(j);
}
public static void popper(int length) {
// pop from stack1 , rotate each word n times and push to stack 2
if (top1 > -1) {
while (top1 > -1) {
word = pop(1);
for (int j = 0; j < length; j++) {
rotate(length);
push(word, 2);
}
}
}
// pop from stack2 , rotate each word n times w.r.t position and push to
// stack 1
else {
while (top2 > -1) {
word = pop(2);
for (int j = 0; j < length; j++) {
rotate(length);
push(word, 1);
}
}
}
}
public static void rotate(int position) {
char[] charstring = new char[100];
for (int j = 0; j < word.length(); j++)
charstring[j] = word.charAt(j);
int startpos = strlength - position;
char temp = charstring[startpos];
for (int i = startpos; i < strlength - 1; i++) {
charstring[i] = charstring[i + 1];
}
charstring[strlength - 1] = temp;
word = new String(charstring).trim();
}
public static void display() {
int top;
if (top1 > -1) {
while (top1 > -1)
System.out.println(stringArray1[top1--]);
} else {
while (top2 > -1)
System.out.println(stringArray2[top2--]);
}
}
}
Another simple way is to loop through the string, pick the character that is not used yet and put it to a buffer, continue the loop till the buffer size equals to the string length. I like this back tracking solution better because:
Easy to understand
Easy to avoid duplication
The output is sorted
Here is the java code:
List<String> permute(String str) {
if (str == null) {
return null;
}
char[] chars = str.toCharArray();
boolean[] used = new boolean[chars.length];
List<String> res = new ArrayList<String>();
StringBuilder sb = new StringBuilder();
Arrays.sort(chars);
helper(chars, used, sb, res);
return res;
}
void helper(char[] chars, boolean[] used, StringBuilder sb, List<String> res) {
if (sb.length() == chars.length) {
res.add(sb.toString());
return;
}
for (int i = 0; i < chars.length; i++) {
// avoid duplicates
if (i > 0 && chars[i] == chars[i - 1] && !used[i - 1]) {
continue;
}
// pick the character that has not used yet
if (!used[i]) {
used[i] = true;
sb.append(chars[i]);
helper(chars, used, sb, res);
// back tracking
sb.deleteCharAt(sb.length() - 1);
used[i] = false;
}
}
}
Input str: 1231
Output list: {1123, 1132, 1213, 1231, 1312, 1321, 2113, 2131, 2311, 3112, 3121, 3211}
Noticed that the output is sorted, and there is no duplicate result.
Recursion is not necessary, even you can calculate any permutation directly, this solution uses generics to permute any array.
Here is a good information about this algorihtm.
For C# developers here is more useful implementation.
public static void main(String[] args) {
String word = "12345";
Character[] array = ArrayUtils.toObject(word.toCharArray());
long[] factorials = Permutation.getFactorials(array.length + 1);
for (long i = 0; i < factorials[array.length]; i++) {
Character[] permutation = Permutation.<Character>getPermutation(i, array, factorials);
printPermutation(permutation);
}
}
private static void printPermutation(Character[] permutation) {
for (int i = 0; i < permutation.length; i++) {
System.out.print(permutation[i]);
}
System.out.println();
}
This algorithm has O(N) time and space complexity to calculate each permutation.
public class Permutation {
public static <T> T[] getPermutation(long permutationNumber, T[] array, long[] factorials) {
int[] sequence = generateSequence(permutationNumber, array.length - 1, factorials);
T[] permutation = generatePermutation(array, sequence);
return permutation;
}
public static <T> T[] generatePermutation(T[] array, int[] sequence) {
T[] clone = array.clone();
for (int i = 0; i < clone.length - 1; i++) {
swap(clone, i, i + sequence[i]);
}
return clone;
}
private static int[] generateSequence(long permutationNumber, int size, long[] factorials) {
int[] sequence = new int[size];
for (int j = 0; j < sequence.length; j++) {
long factorial = factorials[sequence.length - j];
sequence[j] = (int) (permutationNumber / factorial);
permutationNumber = (int) (permutationNumber % factorial);
}
return sequence;
}
private static <T> void swap(T[] array, int i, int j) {
T t = array[i];
array[i] = array[j];
array[j] = t;
}
public static long[] getFactorials(int length) {
long[] factorials = new long[length];
long factor = 1;
for (int i = 0; i < length; i++) {
factor *= i <= 1 ? 1 : i;
factorials[i] = factor;
}
return factorials;
}
}
My implementation based on Mark Byers's description above:
static Set<String> permutations(String str){
if (str.isEmpty()){
return Collections.singleton(str);
}else{
Set <String> set = new HashSet<>();
for (int i=0; i<str.length(); i++)
for (String s : permutations(str.substring(0, i) + str.substring(i+1)))
set.add(str.charAt(i) + s);
return set;
}
}
Permutation of String:
public static void main(String args[]) {
permu(0,"ABCD");
}
static void permu(int fixed,String s) {
char[] chr=s.toCharArray();
if(fixed==s.length())
System.out.println(s);
for(int i=fixed;i<s.length();i++) {
char c=chr[i];
chr[i]=chr[fixed];
chr[fixed]=c;
permu(fixed+1,new String(chr));
}
}
Here is another simpler method of doing Permutation of a string.
public class Solution4 {
public static void main(String[] args) {
String a = "Protijayi";
per(a, 0);
}
static void per(String a , int start ) {
//bse case;
if(a.length() == start) {System.out.println(a);}
char[] ca = a.toCharArray();
//swap
for (int i = start; i < ca.length; i++) {
char t = ca[i];
ca[i] = ca[start];
ca[start] = t;
per(new String(ca),start+1);
}
}//per
}
A java implementation to print all the permutations of a given string considering duplicate characters and prints only unique characters is as follow:
import java.util.Set;
import java.util.HashSet;
public class PrintAllPermutations2
{
public static void main(String[] args)
{
String str = "AAC";
PrintAllPermutations2 permutation = new PrintAllPermutations2();
Set<String> uniqueStrings = new HashSet<>();
permutation.permute("", str, uniqueStrings);
}
void permute(String prefixString, String s, Set<String> set)
{
int n = s.length();
if(n == 0)
{
if(!set.contains(prefixString))
{
System.out.println(prefixString);
set.add(prefixString);
}
}
else
{
for(int i=0; i<n; i++)
{
permute(prefixString + s.charAt(i), s.substring(0,i) + s.substring(i+1,n), set);
}
}
}
}
String permutaions using Es6
Using reduce() method
const permutations = str => {
if (str.length <= 2)
return str.length === 2 ? [str, str[1] + str[0]] : [str];
return str
.split('')
.reduce(
(acc, letter, index) =>
acc.concat(permutations(str.slice(0, index) + str.slice(index + 1)).map(val => letter + val)),
[]
);
};
console.log(permutations('STR'));
In case anyone wants to generate the permutations to do something with them, instead of just printing them via a void method:
static List<int[]> permutations(int n) {
class Perm {
private final List<int[]> permutations = new ArrayList<>();
private void perm(int[] array, int step) {
if (step == 1) permutations.add(array.clone());
else for (int i = 0; i < step; i++) {
perm(array, step - 1);
int j = (step % 2 == 0) ? i : 0;
swap(array, step - 1, j);
}
}
private void swap(int[] array, int i, int j) {
int buffer = array[i];
array[i] = array[j];
array[j] = buffer;
}
}
int[] nVector = new int[n];
for (int i = 0; i < n; i++) nVector [i] = i;
Perm perm = new Perm();
perm.perm(nVector, n);
return perm.permutations;
}

I need help updating an array in main from a method

This is the Main.java
Scanner input = new Scanner(System.in);
String in="t";
String [] t=new String[15];
int c=0;
int p=0;
String n="p";
for(int i=0;i<15;i++){
System.out.print("Enter a topping (or type quit):");
n=input.nextLine();
if(n.equals("quit")){
i=16;
p=1;
}else
t[i]=n;
c++;
}
String [] q=new String[c];
if(t[c-1]==null){
q=new String[c-1];
for(int u=0;u<c-1;u++){
q[u]=t[u];
}
Arrays.sort(q);
if(p==0){
System.out.println("No more toppings allowed.");
}
for(int o=0;o<c-1;o++){
System.out.println((o+1)+". "+q[o]);
}
}
else{
q=new String[c];
for(int u=0;u<c;u++){
q[u]=t[u];
}
Arrays.sort(q);
if(p==0){
System.out.println("No more toppings allowed.");
}
for(int o=0;o<c;o++){
System.out.println((o+1)+". "+q[o]);
}
}
BinarySearch bs = new BinarySearch();
System.out.println("\nWhat do you want to search for?");
String search = input.nextLine();
System.out.println("BinarySearch: "+bs.binarySearch(q, search));
This is the BinarySearch.java class
public void printTopping() {
}
public boolean addTopping(String top) {
}
public int binarySearch(String[] words, String key) {
int left = 0;
int right = words.length - 1;
int mid = 0;
while (left <= right) {
mid = (left + right) / 2;
if ((words[mid] + "").trim().compareTo(key.trim()) < 0) {
left = mid + 1;
} else if ((words[mid] + "").trim().compareTo(key.trim()) > 0) {
right = mid - 1;
} else {
return mid;
}
}
return -1;
}
How do I use the addTopping method to add an topping into the q array in main without there being a String array parameter in the addTopping method? Can I get help writing this method? Then How would i do printTopping() method?
This is the direction :
In main:
String[] toppingStringArray = Arrays.copyOf(q, q.length + 1);
In addTopping:
toppingStringArray[toppingStringArray.length - 1] = top;

quicksort method exception [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I am trying to read names from a file into an String array and use binary search to find the name based on what the user types in but I keep getting a null pointer exception? I feel like it has something to do with the comparators when seeing if anything returns a null but i am not 100% sure if its that.
import java.util.*;
import java.io.*;
public class nameSearch{
static String names[];
int length;
public static void main(String[] args)throws IOException{
nameSearch sorter = new nameSearch();
File f = new File("names.txt");
Scanner scan = new Scanner(f);
Scanner input = new Scanner(System.in);
names = new String[65];
int counter = 0;
while(scan.hasNext()){
counter = counter + 1;
scan.next();
for(int i=0; i < counter; i=i+1){
names[i] = scan.next();
System.out.println(names[i].toString());
}
}
sorter.sort(names);
System.out.println(names.toString());
scan.close();
System.out.println("Enter a name you want to search: ");
String s = input.nextLine();
sorter.binarySearch(s, names);
}
public String toString(){
return "Name: "+ names;
}
void sort(String[] array) {
if (array == null || array.length == 0) {
return;
}
this.names = array;
this.length = array.length;
quickSort(0, length - 1);
}
void quickSort(int lowerIndex, int higherIndex) {
int i = lowerIndex;
int j = higherIndex;
String pivot = this.names[lowerIndex + (higherIndex - lowerIndex) / 2];
while (i <= j) {
while (this.names[i].compareToIgnoreCase(pivot) < 0) {
i++;
}
while (this.names[j].compareToIgnoreCase(pivot) > 0) {
j--;
}
if (i <= j) {
exchangeNames(i, j);
i++;
j--;
}
}
if (lowerIndex < j) {
quickSort(lowerIndex, j);
}
if (i < higherIndex) {
quickSort(i, higherIndex);
}
}
void exchangeNames(int i, int j) {
String temp = this.names[i];
this.names[i] = this.names[j];
this.names[j] = temp;
}
void binarySearch(String s, String[] ar){
String stringToFind = s;
int lowestIndex = 0;
int highestIndex = ar.length-1;
int middleIndex = 0;
while(lowestIndex<=highestIndex){
middleIndex = (lowestIndex+highestIndex)/2;
if(stringToFind.compareTo(ar[middleIndex]) > 0){
lowestIndex = middleIndex+1;
}else if(stringToFind.compareTo(ar[middleIndex]) < 0){
highestIndex = middleIndex - 1;
}else{
break;
}
}
if(lowestIndex > highestIndex){
System.out.println("not found");
}else{
System.out.println("found at " + middleIndex);
}
}
}
The compiler is telling me that there is a null pointer exception on: sorter.sort(names) , quicksort(0, length-1), and starting at:
while (this.names[i].compareToIgnoreCase(pivot) < 0) {
In line 16 you have defined names as String[65] and probably there is no 65 names in your file. so some of names elements are null.
try using arrayList.
public class NameSearch{
static ArrayList<String> names;
int length;
public static void main(String[] args)throws IOException{
NameSearch sorter = new NameSearch();
File f = new File("src/names.txt");
Scanner scan = new Scanner(f);
Scanner input = new Scanner(System.in);
names = new ArrayList<>();
int counter = 0;
while(scan.hasNext()){
names.add(scan.next());
}
sorter.sort(names);
System.out.println(names.toString());
scan.close();
System.out.println("Enter a name you want to search: ");
String s = input.nextLine();
sorter.binarySearch(s, names);
}
public String toString(){
return "Name: "+ names;
}
void sort(ArrayList<String> array) {
if (array == null || array.size() == 0) {
return;
}
this.names = array;
this.length = array.size();
quickSort(0, length - 1);
}
void quickSort(int lowerIndex, int higherIndex) {
int i = lowerIndex;
int j = higherIndex;
String pivot = this.names.get(lowerIndex + (higherIndex - lowerIndex) / 2);
while (i <= j) {
while (this.names.get(i).compareToIgnoreCase(pivot) < 0) {
i++;
}
while (this.names.get(j).compareToIgnoreCase(pivot) > 0) {
j--;
}
if (i <= j) {
exchangeNames(i, j);
i++;
j--;
}
}
if (lowerIndex < j) {
quickSort(lowerIndex, j);
}
if (i < higherIndex) {
quickSort(i, higherIndex);
}
}
void exchangeNames(int i, int j) {
Collections.swap(this.names, i, j);
}
void binarySearch(String s, ArrayList<String> ar){
String stringToFind = s;
int lowestIndex = 0;
int highestIndex = ar.size()-1;
int middleIndex = 0;
while(lowestIndex<=highestIndex){
middleIndex = (lowestIndex+highestIndex)/2;
if(stringToFind.compareTo(ar.get(middleIndex)) > 0){
lowestIndex = middleIndex+1;
}else if(stringToFind.compareTo(ar.get(middleIndex)) < 0){
highestIndex = middleIndex - 1;
}else{
break;
}
}
if(lowestIndex > highestIndex){
System.out.println("not found");
}else{
System.out.println("found at " + middleIndex);
}
}
}

Find the first non repeating character in a string

I m writing a method to find the first non repeating character in a string. I saw this method in a previous stackoverflow question
public static char findFirstNonRepChar(String input){
char currentChar = '\0';
int len = input.length();
for(int i=0;i<len;i++){
currentChar = input.charAt(i);
if((i!=0) && (currentChar!=input.charAt(i-1)) && (i==input.lastIndexOf(currentChar))){
return currentChar;
}
}
return currentChar;
}
I came up with a solution using a hashtable where I have two for loops (not nested) where I interate through the string in one loop writing down each occurance of a letter (for example in apple, a would have 1, p would have 2, etc.) then in the second loop I interate through the hashtable to see which one has a count of 1 first. What is the benefit to the above method over what I came up with? I am new to Java does having two loops (not nested) hinder time complexity. Both these algorithms should have O(n) right? Is there another faster, less space complexity algorithm for this question than these two solutions?
public class FirstNonRepeatCharFromString {
public static void main(String[] args) {
String s = "java";
for(Character ch:s.toCharArray()) {
if(s.indexOf(ch) == s.lastIndexOf(ch)) {
System.out.println("First non repeat character = " + ch);
break;
}
}
}
}
As you asked if your code is from O(n) or not, I think it's not, because in the for loop, you are calling lastIndexOf and it's worst case is O(n). So it is from O(n^2).
About your second question: having two loops which are not nested, also makes it from O(n).
If assuming non unicode characters in your input String, and Uppercase or Lowercase characters are assumed to be different, the following would do it with o(n) and supports all ASCII codes from 0 to 255:
public static Character getFirstNotRepeatedChar(String input) {
byte[] flags = new byte[256]; //all is initialized by 0
for (int i = 0; i < input.length(); i++) { // O(n)
flags[(int)input.charAt(i)]++ ;
}
for (int i = 0; i < input.length(); i++) { // O(n)
if(flags[(int)input.charAt(i)] > 0)
return input.charAt(i);
}
return null;
}
Thanks to Konstantinos Chalkias hint about the overflow, if your input string has more than 127 occurrence of a certain character, you can change the type of flags array from byte[] to int[] or long[] to prevent the overflow of byte type.
Hope it would be helpful.
The algorithm you showed is slow: it looks for each character in the string, it basically means that for each character you spend your time checking the string twice!! Huge time loss.
The best naive O(n) solution basically holds all the characters in order of insertion (so the first can be found) and maps a mutable integer to them. When we're done, analyzing, we go through all the entries and return the first character that was registered and has a count of 1.
There are no restrictions on the characters you can use. And AtomicInteger is available with import java.util.concurrent.atomic.AtomicInteger.
Using Java 8:
public static char findFirstNonRepChar(String string) {
Map<Integer,Long> characters = string.chars().boxed()
.collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()));
return (char)(int)characters.entrySet().stream()
.filter(e -> e.getValue() == 1L)
.findFirst()
.map(Map.Entry::getKey)
.orElseThrow(() -> new RuntimeException("No unrepeated character"));
}
Non Java 8 equivalent:
public static char findFirstNonRepChar(String string) {
Map<Character, AtomicInteger> characters = new LinkedHashMap<>(); // preserves order of insertion.
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
AtomicInteger n = characters.get(c);
if (n == null) {
n = new AtomicInteger(0);
characters.put(c, n);
}
n.incrementAndGet();
}
for (Map.Entry<Character, AtomicInteger> entry: characters.entries()) {
if (entry.getValue().get() == 1) {
return entry.getKey();
}
}
throw new RuntimeException("No unrepeated character");
}
import java.util.LinkedHashMap;
import java.util.Map;
public class getFirstNonRep {
public static char get(String s) throws Exception {
if (s.length() == 0) {
System.out.println("Fail");
System.exit(0);
} else {
Map<Character, Integer> m = new LinkedHashMap<Character, Integer>();
for (int i = 0; i < s.length(); i++) {
if (m.containsKey(s.charAt(i))) {
m.put(s.charAt(i), m.get(s.charAt(i)) + 1);
} else {
m.put(s.charAt(i), 1);
}
}
for (Map.Entry<Character, Integer> hm : m.entrySet()) {
if (hm.getValue() == 1) {
return hm.getKey();
}
}
}
return 0;
}
public static void main(String[] args) throws Exception {
System.out.print(get("Youssef Zaky"));
}
}
This solution takes less space and less time, since we iterate the string only one time.
Works for any type of characters.
String charHolder; // Holds
String testString = "8uiuiti080t8xt8t";
char testChar = ' ';
int count = 0;
for (int i=0; i <= testString.length()-1; i++) {
testChar = testString.charAt(i);
for (int j=0; j < testString.length()-1; j++) {
if (testChar == testString.charAt(j)) {
count++;
}
}
if (count == 1) { break; };
count = 0;
}
System.out.println("The first not repeating character is " + testChar);
I accumulated all possible methods with string length 25'500 symbols:
private static String getFirstUniqueChar(String line) {
String result1 = null, result2 = null, result3 = null, result4 = null, result5 = null;
int length = line.length();
long start = System.currentTimeMillis();
Map<Character, Integer> chars = new LinkedHashMap<Character, Integer>();
char[] charArray1 = line.toCharArray();
for (int i = 0; i < length; i++) {
char currentChar = charArray1[i];
chars.put(currentChar, chars.containsKey(currentChar) ? chars.get(currentChar) + 1 : 1);
}
for (Map.Entry<Character, Integer> entry : chars.entrySet()) {
if (entry.getValue() == 1) {
result1 = entry.getKey().toString();
break;
}
}
long end = System.currentTimeMillis();
System.out.println("1st test:\n result: " + result1 + "\n time: " + (end - start));
start = System.currentTimeMillis();
for (int i = 0; i < length; i++) {
String current = Character.toString(line.charAt(i));
String left = line.substring(0, i);
if (!left.contains(current)) {
String right = line.substring(i + 1);
if (!right.contains(current)) {
result2 = current;
break;
}
}
}
end = System.currentTimeMillis();
System.out.println("2nd test:\n result: " + result2 + "\n time: " + (end - start));
start = System.currentTimeMillis();
for (int i = 0; i < length; i++) {
char currentChar = line.charAt(i);
if (line.indexOf(currentChar) == line.lastIndexOf(currentChar)) {
result3 = Character.toString(currentChar);
break;
}
}
end = System.currentTimeMillis();
System.out.println("3rd test:\n result: " + result3 + "\n time: " + (end - start));
start = System.currentTimeMillis();
char[] charArray4 = line.toCharArray();
for (int i = 0; i < length; i++) {
char currentChar = charArray4[i];
int count = 0;
for (int j = 0; j < length; j++) {
if (currentChar == charArray4[j] && i != j) {
count++;
break;
}
}
if (count == 0) {
result4 = Character.toString(currentChar);
break;
}
}
end = System.currentTimeMillis();
System.out.println("4th test:\n result: " + result4 + "\n time: " + (end - start));
start = System.currentTimeMillis();
for (int i = 0; i < length; i++) {
char currentChar = line.charAt(i);
int count = 0;
for (int j = 0; j < length; j++) {
if (currentChar == line.charAt(j) && i != j) {
count++;
break;
}
}
if (count == 0) {
result5 = Character.toString(currentChar);
break;
}
}
end = System.currentTimeMillis();
System.out.println("5th test:\n result: " + result5 + "\n time: " + (end - start));
return result1;
}
And time results (5 times):
1st test:
result: g
time: 13, 12, 12, 12, 14
2nd test:
result: g
time: 55, 56, 59, 70, 59
3rd test:
result: g
time: 2, 3, 2, 2, 3
4th test:
result: g
time: 3, 3, 2, 3, 3
5th test:
result: g
time: 6, 5, 5, 5, 6
public static char NonReapitingCharacter(String str) {
Set<Character> s = new HashSet();
char ch = '\u0000';
for (char c : str.toCharArray()) {
if (s.add(c)) {
if (c == ch) {
break;
} else {
ch = c;
}
}
}
return ch;
}
Okay I misread the question initially so here's a new solution. I believe is this O(n). The contains(Object) of HashSet is O(1), so we can take advantage of that and avoid a second loop. Essentially if we've never seen a specific char before, we add it to the validChars as a potential candidate to be returned. The second we see it again however, we add it to the trash can of invalidChars. This prevents that char from being added again. At the end of the loop (you have to loop at least once no matter what you do), you'll have a validChars hashset with n amount of elements. If none are there, then it will return null from the Character class. This has a distinct advantage as the char class has no good way to return a 'bad' result so to speak.
public static Character findNonRepeatingChar(String x)
{
HashSet<Character> validChars = new HashSet<>();
HashSet<Character> invalidChars = new HashSet<>();
char[] array = x.toCharArray();
for (char c : array)
{
if (validChars.contains(c))
{
validChars.remove(c);
invalidChars.add(c);
}
else if (!validChars.contains(c) && !invalidChars.contains(c))
{
validChars.add(c);
}
}
return (!validChars.isEmpty() ? validChars.iterator().next() : null);
}
If you are only interested for characters in the range a-z (lowercase as OP requested in comments), you can use this method that requires a minimum extra storage of two bits per character Vs a HashMap approach.
/*
* It works for lowercase a-z
* you can scale it to add more characters
* eg use 128 Vs 26 for ASCII or 256 for extended ASCII
*/
public static char getFirstNotRepeatedChar(String input) {
boolean[] charsExist = new boolean[26];
boolean[] charsNonUnique = new boolean[26];
for (int i = 0; i < input.length(); i++) {
int index = 'z' - input.charAt(i);
if (!charsExist[index]) {
charsExist[index] = true;
} else {
charsNonUnique[index] = true;
}
}
for (int i = 0; i < input.length(); i++) {
if (!charsNonUnique['z' - input.charAt(i)])
return input.charAt(i);
}
return '?'; //example return of no character found
}
In case of two loops (not nested) the time complexity would be O(n).
The second solution mentioned in the question can be implemented as:
We can use string characters as keys to a map and maintain their count. Following is the algorithm.
1.Scan the string from left to right and construct the count map.
2.Again, scan the string from left to right and check for count of each character from the map, if you find an element who’s count is 1, return it.
package com.java.teasers.samples;
import java.util.Map;
import java.util.HashMap;
public class NonRepeatCharacter {
public static void main(String[] args) {
String yourString = "Hi this is javateasers";//change it with your string
Map<Character, Integer> characterMap = new HashMap<Character, Integer>();
//Step 1 of the Algorithm
for (int i = 0; i < yourString.length(); i++) {
Character character = yourString.charAt(i);
//check if character is already present
if(null != characterMap.get(character)){
//in case it is already there increment the count by 1.
characterMap.put(character, characterMap.get(character) + 1);
}
//in case it is for the first time. Put 1 to the count
else
characterMap.put(character, 1);
}
//Step 2 of the Algorithm
for (int i = 0; i < yourString.length(); i++) {
Character character = yourString.charAt(i);
int count = characterMap.get(character);
if(count == 1){
System.out.println("character is:" + character);
break;
}
}
}
}
public char firstNonRepeatedChar(String input) {
char out = 0;
int length = input.length();
for (int i = 0; i < length; i++) {
String sub1 = input.substring(0, i);
String sub2 = input.substring(i + 1);
if (!(sub1.contains(input.charAt(i) + "") || sub2.contains(input
.charAt(i) + ""))) {
out = input.charAt(i);
break;
}
}
return out;
}
Since LinkedHashMap keeps the order of insertion
package com.company;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static void main(String[] argh) {
Scanner sc = new Scanner(System.in);
String l = sc.nextLine();
System.out.println(firstCharNoRepeated(l));
}
private static String firstCharNoRepeated(String l) {
Map<String, Integer> chars = new LinkedHashMap();
for(int i=0; i < l.length(); i++) {
String c = String.valueOf(l.charAt(i));
if(!chars.containsKey(c)){
chars.put(c, i);
} else {
chars.remove(c);
}
}
return chars.keySet().iterator().next();
}
}
Few lines of code, works for me.
public class FirstNonRepeatingCharacter {
final static String string = "cascade";
public static void main(String[] args) {
char[] charArr = string.toCharArray();
for (int i = 0; charArr.length > i; i++) {
int count = 0;
for (int j = 0; charArr.length > j; j++) {
if (charArr[i] == charArr[j]) {
count++;
}
}
if (count == 1){
System.out.println("First Non Repeating Character is: " + charArr[i]);
break;
}
}
}
}
Constraint for this solution:
O(n) time complexity. My solution is O(2n), follow Time Complexity analysis,O(2n) => O(n)
import java.util.HashMap;
public class FindFirstNonDuplicateCharacter {
public static void main(String args[]) {
System.out.println(findFirstNonDuplicateCharacter("abacbcefd"));
}
private static char findFirstNonDuplicateCharacter(String s) {
HashMap<Character, Integer> chDupCount = new HashMap<Character, Integer>();
char[] charArr = s.toCharArray();
for (char ch: charArr) { //first loop, make the tables and counted duplication by key O(n)
if (!chDupCount.containsKey(ch)) {
chDupCount.put(ch,1);
continue;
}
int dupCount = chDupCount.get(ch)+1;
chDupCount.replace(ch, dupCount);
}
char res = '-';
for(char ch: charArr) { //second loop, get the first duplicate by count number, O(2n)
// System.out.println("key: " + ch+", value: " + chDupCount.get(ch));
if (chDupCount.get(ch) == 1) {
res = ch;
break;
}
}
return res;
}
}
Hope it help
char firstNotRepeatingCharacter(String s) {
for(int i=0; i< s.length(); i++){
if(i == s.lastIndexOf(s.charAt(i)) && i == s.indexOf(s.charAt(i))){
return s.charAt(i);
}
}
return '_';
}
String a = "sampapl";
char ar[] = a.toCharArray();
int dya[] = new int[256];
for (int i = 0; i < dya.length; i++) {
dya[i] = -1;
}
for (int i = 0; i < ar.length; i++) {
if (dya[ar[i]] != -1) {
System.out.println(ar[i]);
break;
} else {
dya[ar[i]] = ar[i];
}
}
This is solution in python:
input_str = "interesting"
#input_str = "aabbcc"
#input_str = "aaaapaabbcccq"
def firstNonRepeating(param):
counts = {}
for i in range(0, len(param)):
# Store count and index repectively
if param[i] in counts:
counts[param[i]][0] += 1
else:
counts[param[i]] = [1, i]
result_index = len(param) - 1
for x in counts:
if counts[x][0] == 1 and result_index > counts[x][1]:
result_index = counts[x][1]
return result_index
result_index = firstNonRepeating(input_str)
if result_index == len(input_str)-1:
print("no such character found")
else:
print("first non repeating charater found: " + input_str[result_index])
Output:
first non repeating charater found: r
import java.util.*;
public class Main {
public static void main(String[] args) {
String str1 = "gibblegabbler";
System.out.println("The given string is: " + str1);
for (int i = 0; i < str1.length(); i++) {
boolean unique = true;
for (int j = 0; j < str1.length(); j++) {
if (i != j && str1.charAt(i) == str1.charAt(j)) {
unique = false;
break;
}
}
if (unique) {
System.out.println("The first non repeated character in String is: " + str1.charAt(i));
break;
}
}
}
}
public class GFG {
public static void main(String[] args) {
String s = "mmjjjjmmn";
for (char c : s.toCharArray()) {
if (s.indexOf(c) == s.lastIndexOf(c)) {
System.out.println("First non repeated is:" + c);
break;
}
}
}
output = n
Non Repeated Character String in Java
public class NonRepeatedCharacter {
public static void main(String[] args) {
String s = "ffeeddbbaaclck";
for (int i = 0; i < s.length(); i++) {
boolean unique = true;
for (int j = 0; j < s.length(); j++) {
if (i != j && s.charAt(i) == s.charAt(j)) {
unique = false;
break;
}
}
if (unique) {
System.out.println("First non repeated characted in String \""
+ s + "\" is:" + s.charAt(i));
break;
}
}
}
}
Output:
First non repeated characted in String "ffeeddbbaaclck" is:l
For More Details
In this coding i use length of string to find the first non repeating letter.
package com.string.assingment3;
import java.util.Scanner;
public class FirstNonRepetedChar {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter a String : ");
String str = in.next();
char[] ch = str.toCharArray();
int length = ch.length;
int x = length;
for(int i=0;i<length;i++) {
x = length-i;
for(int j=i+1;j<length;j++) {
if(ch[i]!=ch[j]) {
x--;
}//if
}//inner for
if(x==1) {
System.out.println(ch[i]);
break;
}
else {
continue;
}
}//outer for
}
}// develope by NDM
In Kotlin
fun firstNonRepeating(string: String): Char?{
//Get a copy of the string
var copy = string
//Slice string into chars then convert them to string
string.map { it.toString() }.forEach {
//Replace first occurrance of that character and check if it still has it
if (copy.replaceFirst(it,"").contains(it))
//If it has the given character remove it
copy = copy.replace(it,"")
}
//Return null if there is no non-repeating character
if (copy.isEmpty())
return null
//Get the first character from what left of that string
return copy.first()
}
https://pl.kotl.in/KzL-veYNZ
public static void firstNonRepeatFirstChar(String str) {
System.out.println("The given string is: " + str);
for (int i = 0; i < str.length(); i++) {
boolean unique = true;
for (int j = 0; j < str.length(); j++) {
if (i != j && str.charAt(i) == str.charAt(j)) {
unique = false;
break;
}
}
if (unique) {
System.out.println("The first non repeated character in String is: " + str.charAt(i));
break;
}
}
}
Using Set with single for loop
public static Character firstNonRepeatedCharacter(String str) {
Character result = null;
if (str != null) {
Set<Character> set = new HashSet<>();
for (char c : str.toCharArray()) {
if (set.add(c) && result == null) {
result = c;
} else if (result != null && c == result) {
result = null;
}
}
}
return result;
}
You can achieve this in single traversal of String using LinkedHashSet as follows:
public static Character getFirstNonRepeatingCharacter(String str) {
Set<Character> result = new LinkedHashSet<>(256);
for (int i = 0; i< str.length(); ++i) {
if(!result.add(str.charAt(i))) {
result.remove(str.charAt(i));
}
}
if(result.iterator().hasNext()) {
return result.iterator().next();
}
return null;
}
For Java;
char firstNotRepeatingCharacter(String s) {
HashSet<String> hs = new HashSet<>();
StringBuilder sb =new StringBuilder(s);
for (int i = 0; i<s.length(); i++){
char c = sb.charAt(i);
if(s.indexOf(c) == i && s.indexOf(c, i+1) == -1 ) {
return c;
}
}
return '_';
}
public class FirstNonRepeatingChar {
public static void main(String[] args) {
String s = "hello world i am here";
s.chars().boxed()
.collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))
.entrySet().stream().filter(e -> e.getValue() == 1).findFirst().ifPresent(e->System.out.println(e.getKey()));
}
}
package looping.concepts;
import java.util.Scanner;
public class Line {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter name: ");
String a = sc.nextLine();
int i = 0;
int j = 0;
for (i = 0; i < a.length(); i++) {
char ch = a.charAt(i);
int counter = 0;
// boolean repeat = false;
for (j = 0; j < a.length(); j++) {
if (ch == a.charAt(j)) {
counter++;
}
}
if (counter == 1) {
System.out.print(ch);
}
else
{
System.out.print("There is no non repeated character");
break;
}
}
}
}
import java.util.Scanner;
public class NonRepaeated1
{
public static void main(String args[])
{
String str;
char non_repeat=0;
int len,i,j,count=0;
Scanner s = new Scanner(System.in);
str = s.nextLine();
len = str.length();
for(i=0;i<len;i++)
{
non_repeat=str.charAt(i);
count=1;
for(j=0;j<len;j++)
{
if(i!=j)
{
if(str.charAt(i) == str.charAt(j))
{
count=0;
break;
}
}
}
if(count==1)
break;
}
if(count == 1)
System.out.print("The non repeated character is : " + non_repeat);
}
}
package com.test.util;
public class StringNoRepeat {
public static void main(String args[]) {
String st = "234123nljnsdfsdf41l";
String strOrig=st;
int i=0;
int j=0;
String st1="";
Character ch=' ';
boolean fnd=false;
for (i=0;i<strOrig.length(); i++) {
ch=strOrig.charAt(i);
st1 = ch.toString();
if (i==0)
st = strOrig.substring(1,strOrig.length());
else if (i == strOrig.length()-1)
st=strOrig.substring(0, strOrig.length()-1);
else
st=strOrig.substring(0, i)+strOrig.substring(i+1,strOrig.length());
if (st.indexOf(st1) == -1) {
fnd=true;
j=i;
break;
}
}
if (!fnd)
System.out.println("The first no non repeated character");
else
System.out.println("The first non repeated character is " +strOrig.charAt(j));
}
}

Write a method to print a string with words reversed, without the use of any standard functions [duplicate]

This question already has answers here:
Printing reverse of any String without using any predefined function?
(34 answers)
Closed 8 years ago.
I was asked this in a technical interview. I have no idea whatsoever please please help me.
it goes in infinite loop. I just cant find the correct logic.
not once, but twice i came across this kind of a question, so please help
public static int numberOfCharsInString(String sentence)
{
int numberOfChars = 0,i=0;
while (!sentence.equals(""))
{
sentence = sentence.substring(1);
++numberOfChars;
}
return numberOfChars;
}
public static void reverseSequenceOfWords(String inp)
{
int len=numberOfCharsInString(inp);
char[] in=inp.toCharArray();
int i=0;
for(i=len-1;i>=0;i--)
{
if(in[i]==' ')
{
while(!in.equals("")||in.equals(" "))
{
System.out.print(in[i]+" ");
}
}
else if(in[i]=='\0')
{
break;
}
}
}
public static void main(String[] args)
{
int length=0;
String inpstring = "";
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(input);
try
{
System.out.print("Enter a string to reverse:");
inpstring = reader.readLine();
length=numberOfCharsInString(inpstring);
System.out.println("Number of Characters: "+length);
reverseSequenceOfWords(inpstring);
}
catch (Exception e)
{
e.printStackTrace();
}
}
String[] array = "Are you crazy".split(" ");
for (int i = array.length - 1; i >= 0; --i) {
System.out.print(array[i] + " ");
}
Brute forced this so hard lol
public static void main (String args[]){
String input = new Scanner(System.in).nextLine();
input+=" ";
ArrayList<String> words = new ArrayList<String>();
int start = 0;
for(int i=0; i<input.length(); i++){
if(input.charAt(i)==' '){
String toAdd="";
for(int r=start; r<i; r++){
toAdd+=input.charAt(r);
}
words.add(toAdd);
start = i+1;
}
}
for(int i=words.size()-1; i>=0; i--){
System.out.print(words.get(i)+" ");
}
}
I've used String.length() and String.substring()and String.charAt() - I hope that is allowed.
private static class Word {
private final String message;
private final int start;
private final int end;
public Word(String message, int start, int end) {
this.message = message;
this.start = start;
this.end = end;
}
#Override
public String toString() {
return message.substring(start, end);
}
}
private Word[] split(String message) {
// Split it into words - there cannot be more words than characters in the message.
int[] spaces = new int[message.length()];
// How many words.
int nWords = 0;
// Pretend there's a space at the start.
spaces[0] = -1;
// Walk the message.
for (int i = 0; i < message.length(); i++) {
if (message.charAt(i) == ' ') {
spaces[++nWords] = i;
}
}
// Record the final position.
spaces[++nWords] = message.length();
// Build the word array.
Word[] words = new Word[nWords];
for (int i = 0; i < nWords; i++) {
words[i] = new Word(message, spaces[i] + 1, spaces[i + 1]);
}
return words;
}
private String reverse(String message) {
Word[] split = split(message);
String reversed = "";
for ( int i = split.length - 1; i >= 0; i--) {
reversed += split[i].toString();
if ( i > 0 ) {
reversed += " ";
}
}
return reversed;
}
public void test() {
String message = "Hello how are you today?";
System.out.println(reverse(message));
}
prints
today? you are how Hello
Much more minimal but less useful. Only uses length, charAt and substring again:
public void printWordsReversed(String message) {
int end = message.length();
for ( int i = end - 1; i >= 0; i--) {
if ( message.charAt(i) == ' ') {
System.out.print(message.substring(i+1, end)+" ");
end = i;
}
}
System.out.print(message.substring(0, end));
}
The only function i'm still using is the IndexOf function, but that is not that hard to create for yourself.
static void Main(string[] args)
{
string sentence = "are you cracy";
int length = Program.StringLength(sentence);
int currentpos = 0;
List<string> wordList = new List<string>();
int wordCount = 0;
while (currentpos < length)
{
// find the next space
int spacepos = sentence.IndexOf(' ', currentpos);
string word;
if (spacepos < 0)
{
// end of string reached.
word = sentence.Substring(currentpos, length - currentpos);
wordList.Add(word);
wordCount++;
// no need to continue.
break;
}
word = sentence.Substring(currentpos, spacepos - currentpos);
wordList.Add(word);
wordCount++;
currentpos = spacepos + 1;
}
// display
for (int i = wordList.Count - 1; i >= 0; i--)
{
// after first word is display, add spaces to the output
if (i < wordList.Count - 1)
{
Console.WriteLine(" ");
}
// display word
Console.WriteLine(wordList[i]);
}
}
public static int StringLength(String sentence)
{
int numberOfChars = 0;
while (!sentence.Equals(""))
{
sentence = sentence.Substring(1);
++numberOfChars;
}
return numberOfChars;
}

Categories