I want to find occurrence of each character in their increasing order.
For eg. for input abcddec output should be a1b1c1d1d2e1c2 , but my
code is giving me output as a1b1c2d2e1c2
what changes I should make?
package com.Java8;
public class Occurences {
public static void main(String[] args) {
String str = "abb";
char[] arr = str.toCharArray();
String result = "";
for (int i = 0; i < arr.length; i++) {
int count = 0;
for (int j = 0; j < arr.length; j++) {
if (arr[i] == arr[j]) {
count++;
}
}
result = result + arr[i] + count;
}
System.out.println(result);
}
}
String str = "abcddecca";
char[] arr = str.toCharArray();
StringBuilder sb = new StringBuilder();
Map<Character, Integer> counters = new HashMap<>();
for( int i = 0; i < arr.length; i++ ) {
Integer count = counters.get( arr[i] );
if ( count == null ) {
count = 1;
} else {
count++;
}
counters.put( arr[i], count );
sb.append( arr[i] );
sb.append( count );
}
System.out.println( sb );
I would prefer to create some counters state holder and avoid double FOR loop. Also it's not a good practice to use String concatenation in loops,it's better to use StringBuilder.
Avoid the double for. Store the state in a map or something:
String str="abbcece";
char []charArray=str.toCharArray();
StringBuilder result = new StringBuilder();
Map<Character, Integer> occurenceMap = new HashMap<Character, Integer>();
for(Character character:charArray){
Integer occ = 1;
if(occurenceMap.containsKey(character)){
occ = occurenceMap.get(character)+1;
}
occurenceMap.put(character, occ);
result.append(character).append(occ);
}
System.out.println(result.toString());
Your counting technique counts every time the character appears in the string, not every time the character appears before it in the string + 1. You need to change the forloop to something like this:
for (int i = 0; i < arr.length; i ++){
int count = 1;
for (int j = 0; j < i; j ++){
if(arr[i] == arr[j]){
count ++;
}
}
result = result + arr[i] + count;
}
This will iterate through every character before the character in the forloop and check if they are equal
Your inner for loop upper limit should be less than 'i'.
public class Occurences {
public static void main(String[] args) {
String str = "abb";
char[] arr = str.toCharArray();
String result = "";
for (int i = 0; i < arr.length; i++) {
int count = 1;
for (int j = 0; j < i; j++) { //j upper limit should be i
if (arr[i] == arr[j]) {
count++;
}
}
result = result + arr[i] + count;
}
System.out.println(result);
}
}
You can use a Map to count the occurrence of each letters:
public static void main(String[] args){
String s = "abcddec";
Map<Character, Integer> mapCount = new HashMap<>();
StringBuilder sb = new StringBuilder();
for (char c : s.toCharArray()){
if(mapCount.containsKey(c)){
mapCount.put(c, mapCount.get(c) +1);
}
else mapCount.put(c, 1);
sb.append(String.valueOf(c) + mapCount.get(c));
}
System.out.println(sb.toString());
}
Time complexity of the solution is O(N)
Related
Hi I am trying to mark a position that already been visited
This string
String s = "123+4+3233"
and multiple index.
So I will loop it gotta be inner loop
public static void main(String[] args) {
String s = "123+4+3233";
String n = "";
int count = 0;
List<String> lists = new ArrayList<>();
for(int i=0; i < s.length(); i++){
if(s.charAt(i) > 0){
for(int k = i; k < s.length(); k++){
if(s.charAt(k) == '+'){
break;
}
if(s.charAt(k) != '+'){
n += s.charAt(k);
}
}
if(!(n.isEmpty())){
lists.add(n);
n = "";
}
if(s.charAt(i) == '+'){count++; }
}
}
System.out.println(lists);
}
and this result would come out Since I don't know how to mark the place that already visited.
CANNOT USE SPLIT
[123, 23, 3, 4, 3233, 233, 33, 3]
I just want
EXPECTED RESULT
[123, 4, 3233]
you don't have to mark the place that visited, simply advance the i index:
public static void main(String[] args) {
String s = "123+4+3233";
String n = "";
int count = 0;
List<String> lists = new ArrayList<>();
for(int i=0; i < s.length(); i++){
if(s.charAt(i) > 0){
int k = i;
for(; k < s.length(); k++){
if(s.charAt(k) == '+'){
break;
}
if(s.charAt(k) != '+'){
n += s.charAt(k);
}
}
if(!(n.isEmpty())){
lists.add(n);
n = "";
}
if(s.charAt(i) == '+'){count++; }
if(k > i)i = k - 1; //advance i to the right position
}
}
System.out.println(lists);
}
output:
[123, 4, 3233]
I think you are complicating this one a bit. Here's how I would solve it:
String s = 123+4+3233;
ArrayList<String> nums = new ArrayList<>();
int lastPlus = 0; // Keeping track of the last index at which there was a "+"
for (int j = 0 j < s.length(); j++) {
if (s.charAt(j).equals("+")) {
nums.add(s.substring(lastPlus, j));
lastPlus = j + 1; //The "+1" skips over the plus for the next substring()
}
// This last 'if' statement is for adding that last bit of numbers
if (j == s.length() - 1 && !(s.charAt(j).equals("+"))) {
nums.add(lastPlus);
}
}
This should work.
I think it can be done in a shorter way:
public static void main(String... args){
String s = "123+4+3233";
List<String> lists = new ArrayList<>();
for(int i = 0; i<s.length();i++){
String temp = "";
while(i<s.length() && s.charAt(i) != '+'){
temp+= s.charAt(i);
i++;
}
lists.add(temp);
}
System.out.println(lists);
}
I want to calculate the frequency of the occurrence of all the operators from an input text file. The file contains the operators + and ++. How can I distinguish their respective frequency, as my program treats ++ as 2 distinct + operators rather than 1 ++?
Here is my code (input7.txt is a test file):
public static void main(String[] args) throws IOException {
String string = new String(Files.readAllBytes(Paths.get("input7.txt"))); //String to be counted
int frequencyArray[] = new int[string.length()];
int frequencyArray2[] = new int[string.length()];
char stringArray[] = string.toCharArray(); //Array of characters
int i, j;
//Count characters
for (i = 0; i < string.length(); i++) {
frequencyArray[i] = 1;
//frequencyArray2[i] = 1;
for(j = i + 1; j < string.length(); j++)
{
if(stringArray[i] == stringArray[j])
{
frequencyArray[i]++;
stringArray[j] = '0'; //To avoid revisiting a character
}
}
}
//Display results
System.out.println("Characters and their corresponding frequencies");
for (i = 0; i < frequencyArray.length; i++) {
if (stringArray[i] != ' ' && stringArray[i] != '0') {
System.out.println(stringArray[i] +"-" + frequencyArray[i]);
}
}
}
This works for me:
String s = "sdfasd++ sdfadsf+asdf sdf++sadfasdf++sadfsdf+asdfasdf++";
// create Set with all distinct characters
Set<Character> chars = new HashSet<Character>();
for (int i = 0; i < s.length(); i++) {
chars.add(s.charAt(i));
}
// count distinct characters and put Results in HashMap
Map<Character, Integer> counts = new HashMap<Character, Integer>();
for (Character c : chars) {
int count = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == c)
count++;
}
counts.put(c, count);
}
// Count double-Character-Operators like this
int countPlusPlus = 0;
for (int i = 0; i < s.length() - 1; i++) {
if (s.substring(i, i + 2).equals("++"))
countPlusPlus++;
}
// Calculate totals like this
int singleplusTotal = counts.get('+');
System.out.println("Single Plus total" + singleplusTotal);
System.out.println("Double Plus total" + countPlusPlus);
System.out.println("Only single Plus" + (singleplusTotal - countPlusPlus * 2));
I'm working on a Caesar cipher and I've gotten the majority of the code to work as planned.
the code is supposed to
remove all special characters and spaces
bring everything to uppercase
add spaces at an inputted interval any additional leftover spaces with x's
so for example if i were to type
plaintext: Hi im Doug
key: 1
buffer: 3
my output should be
IJJ NEP VHX
now I've gotten everything to work but the buffer part
this is my code in its entirety
import java.util.Scanner;
import java.lang.String;
public class Main {
public static void main(String[] args) {
System.out.print("Enter plaintext: ");
Scanner pTextInp = new Scanner(System.in);
String pText = pTextInp.nextLine();
System.out.print("Enter key value: ");
Scanner kInp = new Scanner(System.in);
int key = kInp.nextInt();
pText = normalizeText(pText);
pText = caesarify(pText, key);
System.out.print("Enter desired grouping number: ");
Scanner grpInp = new Scanner(System.in);
int grpInt = grpInp.nextInt();
pText = groupify(grpInt, pText);
System.out.println(pText);
}
// CONVERT STRING TO A CHAR ARRAY
public static char[] sArray(String s) {
int sLen = s.length();
char[] sChar = new char[sLen + 1];
for (int i = 0; i < sLen; i++){
sChar[i] = s.charAt(i);
}
return sChar;
}
public static String caesarify(String s, int k) {
int sLen = s.length();
char cText[] = sArray(s);
for (int i = 0; i < sLen; i++){
int j = cText[i] - 65;
int l = (((j + k) % 26) + 65);
cText[i] = (char) l;
}
s = new String(cText);
return s;
}
// normalizes text (removes all spaces and special characters)
public static String normalizeText(String s) {
int sLen = s.length();
char[] t1 = s.toCharArray();
for (int i = 0; i < sLen; i++ ){
if(t1[i] < 'A' || t1[i] > 'z' || (t1[i] > 'Z' && t1[i] < 'a')) {
t1[i] = ' ';
}
else{
t1[i] = s.charAt(i);
}
}
String t = new String(t1);
t = t.replaceAll(" ", "" );
t = t.toUpperCase();
return t;
}
public static String groupify(int i , String s){
int sLen = s.length();
char[] t = new char[sLen];
for (int j = 0; j < s.length(); j++){
t[j] = s.charAt(j);
if ( j % i == 0) {
t[j] = ' ';
sLen++;
}
}
s = new String(t);
return s;
}
and this is the section in particular that i think is the issue
public static String groupify(int i , String s){
int sLen = s.length();
char[] t = new char[sLen];
for (int j = 0; j < s.length(); j++){
t[j] = s.charAt(j);
if ( j % i == 0) {
t[j] = ' ';
sLen++;
}
}
s = new String(t);
return s;
}
with this this if i input
Hi Im Doug
I get
JJ EP H
as output
Thanks a bunch
Currently your code t[i] += ' ' is adding the space character's value to value in the array. That's not what you want. Rather you want to be storing a space in next position. I also suggest that you use better names for your variable - single character variables should generally only be used for indexes.
int pos = 0;
for (int j = 0; j < input.length(); j++)
result[pos++] = input.charAt(j);
if ( j % group == 0) {
result[pos++] = ' ';
}
}
For the code You have highlighted you are missing curly brackets after the for Loop. Try to define j outside the for-loop and assign the value 0 to j in the for-loop. It would be a better practice if you Store the size of your new Char-Array in a separate variable as it is easier to read when finding bugs in the code.
I'm trying to build a function, that gets a string of letters, and prints the amount of each letter in the string.
for example:
input: String = "aaabbaccxyxyx"
output: 4a2b2c3x2y
This is what I've come up with:
public class Q1 {
public static String numLetters(String s){
String end = new String();
int counter = 0;
char c,d;
for(int i=0; i<s.length();i++){
c = s.charAt(i);
for(int j=0; j<s.length();j++){
d = s.charAt(j);
if(c == d){
counter++;
}
}
end = end + counter+c;
counter = 0;
}
return end;
}
but, this is the output: 4a4a4a2b2b4a2c2c3x2y3x2y3x
A lot of repeats..
Any help how to make it right?
Keep in mind, the function needs to return a string, not just prints it out.
Thanks! =)
I would make an int array to keep the count of each letter in in the string. Because there are 26 letters, the length of the array should be 26:
public static String numLetters(String s) {
int[] count = new int[26];
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
count[(int)(c - 'a')]++;
}
String ans = "";
for (int i = 0; i < 26; i++) {
if (count[i] != 0) {
ans += String.valueOf(count[i]) + (char)(i + 'a');
}
}
return ans;
}
A straightforward variant could look like this:
public static String countChars(String arg) {
String res = "";
boolean[] counted = new boolean[arg.length()];
for (int i = 0; i < counted.length; i++) {
if (!counted[i]) {
char c = arg.charAt(i);
int counter = 1;
for (int j = i + 1; j < counted.length; j++) {
if (arg.charAt(j) == c) {
counter++;
counted[j] = true;
}
}
res += counter + "" + c;
}
}
return res;
}
If you want to keep your original structure, I suggest using a StringBuilder so that you can delete characters that you have already seen. In case you delete a character, you have to adjust your indexes i and j.
public static String numLetters(String str){
StringBuilder s = new StringBuilder(s);
String end = new String();
int counter = 0;
char c,d;
for(int i=0; i<s.length();i++){
c = s.charAt(i);
for(int j=0; j<s.length();j++){
d = s.charAt(j);
if(c == d){
s.deleteCharAt(j);
if (i >= j) i--;
j--;
counter++;
}
}
end = end + counter+c;
counter = 0;
}
return end;
}
Try this:
int count = StringUtils.countMatches("a.b.c.d", ".");
What I need to do is take a String array with each element having an exact length of 2, and find all possible combinations of the the elements, using each character within each String. By that I mean the String array {"Ss", "Ff"} returns "SF", "Sf", "sF", "sf". I have already tried a loop method that counts the iteration and then chooses a letter based on that, but it only works for arrays with a single element:
public String [] generatePossibilities(String [] s)
{
if(s[0].length() != 2)
throw new IllegalArgumentException();
String [] r = new String [s.length * 2];
for(int i = 0; i < r.length; i++)
{
r[i] = getPossibility(i, s);
}
return r;
}
private String getPossibility(int iteration, String [] source)
{
int [] choose = new int [source.length];
for(int i = 0; i < choose.length; i++)
{
choose[i] = 0;
}
for(int i = choose.length - 1; i >= 0; i--)
{
if(iteration < 1)
break;
choose[i] = 1;
iteration--;
}
String result = "";
for(int i = 0; i < source.length; i++)
result += source[i].substring(choose[i], choose[i] + 1);
return result;
}
Solved Thanks Sven!
public String [] generatePossibilities(String [] s)
{
if(s[0].length() != 2)
throw new IllegalArgumentException();
ArrayList<String> ra = new ArrayList<String>();
for(int i = s.length - 1; i >= 0; i--)
{
for(int j = 0; j < s[i].length(); j++)
{
String c = s[i].substring(j, j + 1);
if(ra.size() < 2)
{
ra.add(c);
}
else
{
for(int k = 0; k < ra.size(); k++)
{
String s1 = ra.get(k);
if(s1.substring(0, 1).equalsIgnoreCase(c))
continue;
else
{
s1 = c + s1;
ra.add(s1);
}
}
}
}
for(int j = 0; j < ra.size(); j++)
{
if(ra.get(j).length() != s.length - i)
{
ra.remove(j);
j--;
}
}
}
String [] r = new String [ra.size()];
for(int i = 0; i < r.length; i++)
{
r[i] = ra.get(i);
}
return r;
}
I would iterate the array of character tuples from last element to first. In each step you append to each current character the possibilities of the last iteration. You therefore double the elements in each step.
So for your example in the first iteration you have {Ff} and this would result to the two strings "F" and "f". In the next step you take each character of {Ss} and append each string of the last step to it getting "SF", "Sf", "sF" and "sf". You could then continue with further character tuples.