Finding the exponent of a string - java

I got this problem in my programming competency test. I need to find the exponent of a string.
For Eg :
Input Str = "pctpctpct", output : pct 3.
Input str : "pressure", output 0. Because pressure is not repeating as a string.
That is the string pct is repeated 3 times.
I need to create a method for this. I tried everything but failed.
My method was :
public static int findExponent(String str) {
int count = 0;
String subs = "";
ArrayList<String> al = new ArrayList<String>();
for (int i = 0; i < str.length() / 2; i++) {
for (int j = i + 1; j <= str.length() / 2; j++) {
subs = str.substring(i, j);
al.add(subs);
System.out.println(al);
for (String x : al)
for (int k = 0; k < str.length(); k++) {
if (str.contains(x)) {
count++;
}
}
}
}
return count;
}
Here I was checking if any substring matches the pattern of the String. But it is not giving me the correct output. What changes should I need to do in this?
How to check the pattern for such a type of question where we have to create a pattern and check if it's repeated?

How about this. I would go ahead with the algorithm based on java:-
Lets assume the input is the string
convert it to character sequence (array of char)
Sort the array into a temp array
loop from 0 to array length
count the ith letter repetition
if its 0
return 0;
else
if count for all word matches
return count;
complexity is 0(n) and this code would work

Related

returning all string values that meet the condition

Not sure how to set up this method which gets as parameter a String array and has to return in a new array all values that meet the following condition:
25% of characters in every element of array are numbers;
public static String[] returnSentence(String[] str){
int nrOfWords = str.length;
int count = 0;
for(int i = 0; i < nrOfWords; i++){
for(int j = 0; j < str[i].length; j++){
}
}
}
I had an idea that it should be something like this but cant format the code to test the condition...
Your question basically boils down to figuring out how many characters in the String fullfil a given condition, and how many do not.
There is two ways to do this:
1) Simply count the characters:
int numPositiveChars = 0;
int numNegativeChars = 0;
for (int i = 0; i < s.length(); i++){
char c = s.charAt(i);
if (/*check c here*/)
numPositiveChars++;
else
numNegativeChars++;
}
In fact you don't even need to count the negative chars, because that value is simply s.length() - numPositiveChars.
2) Another approach would be to use regular expressions, e.g. by removing all non-numerical characters and then get the character count:
int numPositiveChars = s.replaceAll("[^0-9]+", "").length();
This line will remove all characters from the String that are not numerical (not 0-9) and then return the length of the result (the number of characters that are numerical).
Once you have the number of chars that match your condition, calculating the percentage is trivial.
You need to just replace all non digits in each element and then compare the length like so :
public static List<String> returnSentence(String[] str) {
int nrOfWords = str.length;
List<String> result = new ArrayList<>();
for (int i = 0; i < nrOfWords; i++) {
if(str[i].replaceAll("\\D", "").length() == str[i].length() * 0.25){
result.add(str[i]);
}
}
return result; // If you want an array use : return result.toArray(String[]::new);
}
I would also use as result a List instead of array because you don't have any idea how many element is respect the condition.
If you want to solve with streaming it can be more easier :
public static String[] returnSentence(String[] str) {
return Arrays.stream(str)
.filter(s-> s.replaceAll("\\D", "").length() == s.length() * 0.25)
.toArray(String[]::new);
}
some thing like this
public static String[] returnSentence(String[] str){
int nrOfWords= str.length;
String[] temp_Str = new String[20];
int count = 0;
int k=0;
for(int i = 0;i<nrOfWords;i++){
for(int j = 0;j<str[i].length;j++){
if(Character.isAlphabetic(str[i].getcharat(j)))
{
count++;
}
if((count/100.0)*100>=25)
{ temp_Str[k]=str[i];
k++;
}
}
}
}

in repeated string finding the total number of time the occurrence of any character

Given an integer,n, find and print the number of letter a's in the first n letters of infinite string.
For example, if the string s='abcac' and n=10, the substring we consider is abcacabcac , the first 10 characters of her infinite string. There are 4 occurrences of a in the substring.
static long repeatedString(String s, long n) {
long len = s.length(), count = 0;
StringBuilder sb = new StringBuilder("");
char[] c = s.toCharArray();
for (int i = 0; i < n; i++) {
sb.append(c[(i % len)]);
if (sb.charAt(i) == 'a')
count++;
}
return count;
}
it is showing error
incompatible types: possible lossy conversion from long to int
sb.append(c[i%len]);
if i am type casting the len then it is not passing the test case for the value whose length is greater than 10^9 for example if my input is
a
1000000000000
then the output must be 1000000000000
note-> for any given input i have to calculate the total number of 'a'
present in that given string
EDIT:i am calling my function as
long result = repeatedString("a", 1000000000000);
Part of your question seemed a bit vague, but from the last line, I get that, you want to find number of occurrences of a particular character in a string.
You can use a HashMap to add the unique characters of your String and set the value as the number of occurrences of the character.
What I am saying, looks something like this in code:
HashMap<Character,Integer> hm = new HashMap<Character,Integer>();
char[] str = s.toCharArray();
for(char c : str) {
if(hm.containsKey(c))
hm.put(c, hm.get(c)+1);
else
hm.put(c, 1);
}
Now you can just choose the character of your choice in the string to get it's number of occurrences, like this:
if(hm.get(character)!=null)
ans = hm.get(character);
else
ans = 0;
There is also a library, I am making for this here.
Edit:
From the edit, the question is much more clear, for that all you need to do is to add the characters of your string to the previous string, until the length is met.
After that, you can use the new string like in the code, I've given here.
You don't need a StringBuilder.
Get the result you want by iterating the initial string and multiply it as many times as needed, meaning by (n / len), then add what is left by the division:
static long repeatedString(String s, long n) {
long len = s.length();
if (len == 0)
return 0;
long rep = n / len;
long count = 0;
for (int i = 0; i < len; i++) {
if (s.charAt(i) == 'a')
count++;
}
count *= rep;
long rest = n % len;
for (int i = 0; i < rest; i++) {
if (s.charAt(i) == 'a')
count++;
}
return count;
}
I think you do not have to use StringBuidler (moreover, for big n, this could flow OutOfMemoryError), but count required letters on the fly.
public static long repeatedString(String str, long n, char ch) {
long count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == ch)
continue;
count += n / str.length();
count += i < n % str.length() ? 1 : 0;
}
return count;
}

Java program to find the letter that appears in the most words?

I have a sentence, and I want to find the char that appears in the most words, and how many words it appears in.
For example: "I like visiting my friend Will, who lives in Orlando, Florida."
Which should output I 8.
This is my code:
char maxChar2 = '\0';
int maxCount2 = 1;
for (int j=0; j<strs2.length; j++) {
int charCount = 1;
char localChar = '\0';
for (int k=0; k<strs2[j].length(); k++) {
if (strs2[j].charAt(k) != ' ' && strs2[j].charAt(k) != maxChar2) {
for (int l=k+1; l<strs2[j].length(); l++) {
if (strs2[j].charAt(k)==strs2[j].charAt(l)) {
localChar = strs2[j].charAt(k);
charCount++;
}
}
}
}
if (charCount > maxCount2) {
maxCount2 = charCount;
maxChar2 = localChar;
}
}
, where strs2 is a String array.
My program is giving me O 79. Also, uppercase and lowercase do not matter and avoid all punctuation.
As a tip, try using more meaningful variable names and proper indentation. This will help a lot especially when your program is not doing what you thought it should do. Also starting smaller and writing some tests for it will help a bunch. Instead of a full sentence, get it working for 2 words, then 3 words, then a more elaborate sentence.
Rewriting your code to be a bit more readable:
// Where sentence is: "I like".split(" ");
private static void getMostFrequentLetter(String[] sentence) {
char mostFrequentLetter = '\0';
int mostFrequentLetterCount = 1;
for (String word : sentence) {
int charCount = 1;
char localChar = '\0';
for (int wordIndex = 0; wordIndex < word.length(); wordIndex++) {
char currentLetter = word.charAt(wordIndex);
if (currentLetter != ' ' && currentLetter != mostFrequentLetter) {
for (int l = wordIndex + 1; l < word.length(); l++) {
char nextLetter = word.charAt(l);
if (currentLetter == nextLetter) {
localChar = currentLetter;
charCount++;
}
}
}
}
if (charCount > mostFrequentLetterCount) {
mostFrequentLetterCount = charCount;
mostFrequentLetter = localChar;
}
}
}
Now all I did was rename your variables and change your for loop to a for-each loop. By doing this you can see more clearly your algorithm and what you're trying to do. Basically you're going through each word and comparing the current letter with the next letter to check for duplicates. If I run this with "I like" i should get i 2 but instead I get null char 1. You aren't properly comparing and saving common letters. This isn't giving you the answer, but I hope this makes it more clear what your code is doing so you can fix it.
Here is a somewhat more elegant solution
public static void FindMostPopularCharacter(String input)
{
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
input = input.toUpperCase();
HashMap<Character, Integer> charData = new HashMap<>();
char occursTheMost = 'A'; //start with default most popular char
int maxCount = 0;
//create the map to store counts of all the chars seen
for(int i = 0; i < alphabet.length(); i++)
charData.put(alphabet.charAt(i), 0);
//first find the character to look for
for(int i = 0; i < input.length(); i++)
{
char c = input.charAt(i);
//if contained in our map increment its count
if(charData.containsKey(c))
charData.put(c, charData.get(c) + 1);
//check for a max count and set the values accordingly
if(charData.containsKey(c) && charData.get(c) > maxCount)
{
occursTheMost = c;
maxCount = charData.get(c);
}
}
//final step
//now split it up into words and search which contain our most popular character
String[] words = input.split(" ");
int wordCount = 0;
CharSequence charSequence;
for(Character character : charData.keySet())
{
int tempCount = 0;
charSequence = "" + character;
for(int i = 0; i < words.length; i++)
{
if(words[i].contains(charSequence))
tempCount++;
}
if(tempCount > wordCount)
{
occursTheMost = character;
wordCount = tempCount;
}
}
System.out.println(occursTheMost + " " + wordCount);
}
Output of
String input = "I like visiting my friend Will, who lives in Orlando, Florida.";
FindMostPopularCharacter(input);
is
I 8
Note: If there are ties this will only output the character that first reaches the maximum number of occurrences.
FindMostPopularCharacter("aabb aabb aabb bbaa");
Outputs
B 4
because B reaches the max first before A due to the last word in the input.
FindMostPopularCharacter("aab aab b")
B 3

How to sort integer array without losing location

I'm making a program which receives a string as input and returns the "sum" of the values for each letter of each word.
For example, my input of "Take advantage, do your best, don't stress.", would return:
do(19) take(37) dont(43) best(46) advantage(75) your(79) stress(100)
"do" would have a value of 19 because the letter "d" has a value of 4 (it is the fourth letter of the alphabet), and "o" has a value of 15, so the total is 19.
Now to store these values I have two arrays, one string array for each word, and one int array for the point value that they have. However, I only have this so far:
take(37) advantage(75) do(19) your(79) best(46) dont(53) stress(100)
As you can see, it is not sorted in ascending order as I am trying to do. I display these values like this:
System.out.print(words[j] + "(" + points[j] + ")" + " ");
where words is the String array and points is the int array. How can I sort them?
My current code:
public static void main (String[] args)
{
String input = "Take advantage, do your best, don't stress.";
String output = "";
//Get rid of all punctuation
for(int i = 0; i < input.length(); i++){
if( ( (int)input.charAt(i) >= 65 && (int)input.charAt(i) <= 90) || (int)input.charAt(i) == 32 || ( (int)input.charAt(i) >= 97 && (int)input.charAt(i) <= 122)){
//Handles Uppercase
if(input.charAt(i) >= 65 && input.charAt(i) <= 90){
int temp = (int)input.charAt(i) + 32;
char c = (char)temp;
output += c;
}
//Handles all other characters
else{
output += input.charAt(i);
}
}
}
//Done punctuation
String[] words = output.split(" ");
int[] points = new int[words.length];
//Points assignment
for(int j = 0; j < words.length; j++){
for(int k = 0; k < words[j].length(); k++){
points[j] += (int)words[j].charAt(k) - 96;
}
System.out.print(words[j] + "(" + points[j] + ")" + " ");
}
}
How about storing your results in a Map<String,Integer> instead of two lists:
Map myMap = new HashMap<String,Integer>;
From there you can sort the Map by its values: Sort a Map<Key, Value> by values (Java)
Next you can iterate through the sorted map:
for(String s : myMap.keySet()){
System.out.println(s+"("+myMap.get(s)+")");
}
If that is an option, your code can be made much simpler with Java 8.
First of all, removing punctuation can be done with a simple regular expression: you only want to keep letters, so we can just remove everything that is neither a letter nor a space. This is done by calling replaceAll("[^a-zA-Z\\s]", ""). After that, we can get a hold of all the words by splitting around "\\s+" (i.e. all whitespace characters).
Then, let's create a helper method returning the value of a String. As you have in your question, this would just be:
private static int value(String str) {
return str.chars().map(c -> c - 'a' + 1).sum();
}
Finally, we need to sort the words array with a comparator comparing the value of each word. The comparator is created with the help of Comparator.comparingInt(keyExtractor) where the key extraction would be a function returning the value of a word. In this case, it could be expressed a lambda expression: word -> value(word).
To have the final output, we need to transform the words array into a String where each word is concatenated with its value in parentheses. This is done by creating a Stream<String> of the words (Arrays.stream(array)), sorting it according the comparator above (sorted(comparator)), mapping each word to the result of concatenating its value to it and finally collecting that into a String delimited by a space (Collectors.joining(delimiter)).
Whole code would be:
public static void main(String[] args) {
String str = "Take advantage, do your best, don't stress.";
String[] words = str.toLowerCase().replaceAll("[^a-zA-Z\\s]", "").split("\\s+");
String output =
Arrays.stream(words)
.sorted(Comparator.comparingInt(w -> value(w)))
.map(w -> w + "(" + value(w) + ")")
.collect(Collectors.joining(" "));
System.out.println(output);
}
private static int value(String str) {
return str.chars().map(c -> c - 'a' + 1).sum();
}
Use any of sorting algorithm and do sorting for both arrays. For example:
public static void bubbleSort(int[] numArray, String[] words) {
int n = numArray.length;
int temp = 0;
String tt;
for (int i = 0; i < n; i++) {
for (int j = 1; j < (n - i); j++) {
if (numArray[j - 1] > numArray[j]) {
temp = numArray[j - 1];
tt=words[j-1];
numArray[j - 1] = numArray[j];
words[j-1]=words[j];
numArray[j] = temp;
words[j]=tt;
}
Then change last part of your main function to look like this:
String[] words = output.split(" ");
int[] points = new int[words.length];
//Points assignment
for(int j = 0; j < words.length; j++){
for(int k = 0; k < words[j].length(); k++){
points[j] += (int)words[j].charAt(k) - 96;
}
}
bubbleSort(points,words);
for(int j = 0; j < words.length; j++){
System.out.print(words[j] + "(" + points[j] + ")" + " ");
}
If you are not allowed to use Java 8 (else use #Tunaki's approach), create a Comparable object that keeps two values, a String (word) and an int (sum). Then, just add each word to a list and sort it using Collections.sort(yourList).
public class Word implements Comparable<Word>{
private String word;
private int sum;
public Word(String word) {
this.word = word;
setSum();
}
private void setSum() {
//your sum function, I just copy and paste it from your post
for(int k = 0; k < word.length(); k++)
sum += (int)word.charAt(k) - 96;
}
public String getWord() {
return word;
}
public int getSum() {
return sum;
}
#Override
public int compareTo(Word o) {
return this.sum > o.sum ? 1 : -1;
}
}

Write a program to print each and every alphabet with how many occured in a user input

I have to write a program to accept a String as input, and as output I'll have to print each and every alphabetical letter, and how many times each occurred in the user input. There are some constraints:
I cannot use built-in functions and collection
The printed result should be sorted by occurrence-value.
For example, with this input:
abbbccccdddddzz
I would expect this output:
a-1,z-2,b-3,c-4,d-5
This is what I have so far:
public static void isCountChar(String s) {
char c1[] = s.toCharArray();
int c3[] = new int[26];
for (int i = 0; i < c1.length; i++) {
char c = s.charAt(i);
c3[c - 'a']++;
}
for (int j = 0; j < c3.length; j++) {
if (c3[j] != 0) {
char c = (char) (j + 'a');
System.out.println("character is:" + c + " " + "count is: " + c3[j]);
}
}
}
But I don't know how to sort.
First of all a tip for your next question: The things you've stated in your comments would fit better as an edit to your question. Try to clearly state what the current result is, and what the expected result should be.
That being said, it was an interesting problem, because of the two constraints.
First of all you weren't allowed to use libraries or collections. If this wasn't a constraint I would have suggested a HashMap with character as keys, and int as values, and then the sorting would be easy.
Second constraint was to order by value. Most people here suggested a sorting like BubbleSort which I agree with, but it wouldn't work with your current code because it would sort by alphabetic character instead of output value.
With these two constraints it is probably best to fake key-value pairing yourself by making both an keys-array and values-array, and sort them both at the same time (with something like a BubbleSort-algorithm). Here is the code:
private static final int ALPHABET_SIZE = 26;
public static void isCountChar(String s)
{
// Convert input String to char-array (and uppercase to lowercase)
char[] array = s.toLowerCase().toCharArray();
// Fill the keys-array with the alphabet
char[] keys = new char[ALPHABET_SIZE];
for (int i = 0; i < ALPHABET_SIZE; i++)
{
keys[i] = (char)('a' + i);
}
// Count how much each char occurs in the input String
int[] values = new int[ALPHABET_SIZE];
for (char c : array)
{
values[c - 'a']++;
}
// Sort both the keys and values so the indexes stay the same
bubbleSort(keys, values);
// Print the output:
for (int j = 0; j < ALPHABET_SIZE; j++)
{
if (values[j] != 0)
{
System.out.println("character is: " + keys[j] + "; count is: " + values[j]);
}
}
}
private static void bubbleSort(char[] keys, int[] values)
{
// BUBBLESORT (copied from http://www.java-examples.com/java-bubble-sort-example and modified)
int n = values.length;
for(int i = 0; i < n; i++){
for(int j = 1; j < (n - i); j++){
if(values[j-1] > values[j]){
// Swap the elements:
int tempValue = values[j - 1];
values[j - 1] = values[j];
values[j] = tempValue;
char tempKey = keys[j - 1];
keys[j - 1] = keys[j];
keys[j] = tempKey;
}
}
}
}
Example usage:
public static void main (String[] args) throws java.lang.Exception
{
isCountChar("TestString");
}
Output:
character is: e; count is: 1
character is: g; count is: 1
character is: i; count is: 1
character is: n; count is: 1
character is: r; count is: 1
character is: s; count is: 2
character is: t; count is: 3
Here is a working ideone to see the input and output.
some sort: easy if not easiest to understand an coding
You loop from the first element to the end -1 : element K
compare element K and element K+1: if element K>element K+1, invert them
continue loop
if you made one change redo that !

Categories