I'm trying to write a class and create accessors in Eclipse that I will have to use later on, however I'm having trouble doing so. I have the directions listed below but keep getting stuck on the last two.
Directions:
Write a class StringSet. A StringSet object is given a series of String objects. It stores these Strings (or a reference to them, to be precise) and can perform limited calculations on the entire series. A StringSet class has the following specification:
a single instance variable of type ArrayList<String>
a single default constructor
mutator that adds a String newStr to the StringSet object
void add(String newStr)
accessor that returns the number of String objects that have been added to this StringSet object
int size()
accessor that returns the total number of characters in all of the Strings that have been added to this StringSet object
int numChars()
accessor that returns the number of Strings in the StringSet object that have exactly len characters
int countStrings(int len)
My code so far:
import java.util.ArrayList;
public class StringSet {
ArrayList<String> StringSet = new ArrayList<String>();
public StringSet() {
}
public void add(String newStr) {
StringSet.add(newStr);
}
public int getsize() {
return StringSet.size();
}
public int getnumChars() {
return StringSet.length();
}
public int countStrings(int len) {
if (StringSet.equals(len)) {
return StringSet.size();
}
}
}
Your string set is an array of string objects. Think of it as though you've added each of the following to stringSet (indexes are to the left of the value).
0[Hello]
1[My]
2[name]
3[is]
5[Keith]
For simplicity I'm going to use a primitive String[] rather than an ArrayList
Question 5
Create a variable that will increment its value by the size of each String. Then use a for loop to evaluate each individual String's length and add it to that variable:
int totalCharsInStringSet = 0;
for (int i = 0; i < stringSet.size(); i++) { // loop through each index
// add the length of the string at this index to your running tally
totalCharsInStringSet += stringSet[i].length;
}
// you've read through all of the array; return the result
return totalCharsInStringSet;
Question 6
Calling stringSet.size() is just going to count how many elements are in the array; i.e., 5. So you need to create a tally of how many individual strings match the target length. Craete a variable to keep that tally. And again, use a for loop to iterate through the array, and compare each string's length to the target value. If it matches, increment your tally:
int numberOfMatches = 0;
for (int i = 0; i < stringSet.size(); i++) {
if (string[i].length == len) { // "len" is your input target length
numberOfMatches ++;
}
}
return numMatches;
Number 5: You iterate through your ArrayList and add up the length of the strings stored there.
Number 6: You iterate through you ArrayList and check if the length of the String matches the desired length, and keep track of the number of matching strings.
Well ArrayLists don't have a length() method, so what you need to do to count total number of chars in the string set is iterate through the StringSet list and find the length of each string and add it to a running total.
int sum = 0;
for(int i = 0; i < StringSet.size(); i++){
sum = sum + StringSet.get(i).length();
}
return sum;
For the countStrings you need to place this if statement in a for loop and increment a sum each time the if statement is triggered and return the sum
int sum = 0;
for(int i = 0; i < StringSet.size(); i++){
if(StringSet.get(i).length() == len){
sum = sum + 1;
}
}
return sum;
For Question 5:
public int getnumChars()
{
int countChar = 0;
for(String strSet: StringSet){
countChar += strSet.length();
}
return countChar;
}
For Question 6:
public int countStrings(int len)
{
int count = 0;
for(String strSet: StringSet){
if(strSet.length() == len){
count++;
};
}
return count;
}
Related
I am trying to sum all the int values of a 2D array. I named it array. my function is then called arraySum. If arraySum is null, I return 0. Otherwise, it goes through two for-loops, summing the values of these arrays.
int i = 0;
int j = 0;
static int sum = 0;
int[][] array = new int[i][j];
static int arraySum(int[][] array) {
if (array == null) { // test if the incoming param is null
return 0;
} else {
for (int i = 0; i < array.length; i++) { // length of the outer array
for (int j = 0; j < array[i].length; j++) { // length of the inner array
sum += array[i][j];
}
}
return sum; // moved out of the loop
}
}
my error message:
java.lang.AssertionError: Incorrect result: expected [-217085] but found [-308126]
Fixing the method signature is the first step.
Then you'll need to fix the null check.
Then your loops need to check the size of the inner and outer arrays.
Move the return statement.
Here's the fixed code:
static int arraySum(int[][] array) { // fix the signature
if (array == null) { // test if the incoming param is null
return 0;
} else {
int sum = 0; // you need this in the scope of the method - it will be returned at the end
for (int i = 0; i < array.length; i++) { // length of the outer array
for (int j = 0; j < array[i].length; j++) { // length of the inner array
sum += array[i][j];
}
}
return sum; // moved out of the loop
}
}
Edit: I've concentrated on just the method now - how you call it is up to you. Please note that the method will not affect any externally defined sum variable. It will return the sum and it's up to the caller to store that value somewhere.
Avoid using primitive for statement. See following:
static int arraySum(int[][] array) {
int sum = 0;
if (array == null) return 0;
for(int[] row: array){
for(int col : row) {
sum += col;
}
}
return sum;
}
Streams can do this too:
//Create 2D array
int[][] array = {{1,2,3},{4,5},{6}};
//Sum all elements of array
int sum = Stream.of(array).flatMapToInt(IntStream::of).sum();
System.out.println(sum);
Picking apart the summing code:
Stream.of(array)
Turns the 2D array of type int[][] into a Stream<int[]>. From here, we need to go one level deeper to process each child array in the 2D array as the stream only streams the first dimension.
So at this point we'll have a stream that contains:
an int[] array containing {1,2,3}
an int[] array containing {4,5}
an int[] array containing {6}
.flatMapToInt(IntStream::of)
So far we have a Stream of int[], still two-dimensional. Flat map flattens the structure into a single stream of ints.
flatMapToInt() expands each int[] element of the stream into one or more int values. IntStream.of() takes an array int[] and turns it into an int stream. Combining these two gives a single stream of int values.
After the flattening, we'll have an int stream of:
{1,2,3,4,5,6}
.sum()
Now we have an IntStream with all elements expanded out from the original 2D array, this simply gets the sum of all the values.
Now the disclaimer - if you are new to Java and learning about arrays, this might be a little too advanced. I'd recommend learning about nesting for-loops and iterating over arrays. But it's also useful to know when an API can do a lot of the work for you.
I am having difficulty in making the logic for my scenario which i m considering an array of arrays more specifically said as 2D array.i want to find the maximum value in 2D arrays i do not want to call it in main method.i am making the array as annonymous and calling the function of max from it via static data members.the code is as follows.do let me know the logic to find the greatest no in 2D array as i m finding it difficult to which value to compare with the array.the code is as follows:-
class Max2DArray
{
static int i;
static int j;
static int large;//largest number
int max(int x[][])
{
for(int i=0;i<x.length;i++)
{
for(j=0;j<x[i].length;i++)
{
if(x[i][j]<=???)//what should be the comparison here.
{
??//what should be done here??
}
}
}
return large
}
public static void main(String... s)
{
Max2DArray m1 = new Max2DArray();
int t = m1.max(new int[][]{{20,10,5},
{5,7,6},
{23,31,16}});
System.out.println("the largest number is = "+t);
}
}
I am not going to solve it to you but here is an algorithm
Have a local variable max
assign max to the first value of the array
iterate through the array and change the value of max whenever you find a value greater that the current value of max.
return max
Try this:
int max(int x[][]){
// Initialize the value to the lowest value
int large = Integer.MIN_VALUE;
for(int i = 0; i < x.length; i++) {
for(j = 0; j < x[i].length; j++) {
// Check if the current value is greater than large
if(x[i][j] > large) {
// It is greater so we keep the new value
large = x[i][j];
}
}
}
return large;
}
Using java 8, it could simply be:
int max(int x[][]){
return Arrays.stream(x).flatMapToInt(IntStream::of).max().getAsInt();
}
A Java 8 one-liner, instead of your for loop:
Arrays.stream(x).flatMapToInt(arr2 -> Arrays.stream(arr2)).max().getAsInt();
Let's say I have an array in the length of n, and the only values that can appear in it are 0-9. I want to create a recursive function that returns the number of different values in the array.
For example, for the following array: int[] arr = {0,1,1,2,1,0,1} --> the function will return 3 because the only values appearing in this array are 0, 1 and 2.
The function receives an int array and returns int
something like this:
int numOfValues(int[] arr)
If you are using Java 8, you can do this with a simple one-liner:
private static int numOfValues(int[] arr) {
return (int) Arrays.stream(arr).distinct().count();
}
Arrays.stream(array) returns an IntStream consisting of the elements of the array. Then, distinct() returns an IntStream containing only the distinct elements of this stream. Finally, count() returns the number of elements in this stream.
Note that count() returns a long so we need to cast it to an int in your case.
If you really want a recursive solution, you may consider the following algorithm:
If the input array is of length 1 then the element is distinct so the answer is 1.
Otherwise, let's drop the first element and calculate the number of distinct elements on this new array (by a recursive call). Then, if the first element is contained in this new array, we do not count it again, otherwise we do and we add 1.
This should give you enough insight to implement this in code.
Try like this:
public int myFunc(int[] array) {
Set<Integer> set = new HashSet<Integer>(array.length);
for (int i : array) {
set.add(i);
}
return set.size();
}
i.e, add the elements of array inside Set and then you can return the size of Set.
public int f(int[] array) {
int[] counts = new int[10];
int distinct = 0;
for(int i = 0; i< array.length; i++) counts[array[i]]++;
for(int i = 0; i< counts.length; i++) if(counts[array[i]]!=0) distinct++;
return distinct;
}
You can even change the code to get the occurrences of each value.
You can try following code snippet,
Integer[] arr = {0,1,1,2,1,0,1};
Set<Integer> s = new HashSet<Integer>(Arrays.asList(arr));
Output: [0, 1, 2]
As you asked for a recursive implementation, this is one bad way to do that. I say bad because recursion is not the best way to solve this problem. There are other easier way. You usually use recursion when you want to evaluate the next item based on the previously generated items from that function. Like Fibonacci series.
Ofcourse you will have to clone the array before you use this function otherwise your original array would be changed (call it using countDistinct(arr.clone(), 0);)
public static int countDistinct(int[] arr, final int index) {
boolean contains = false;
if (arr == null || index == arr.length) {
return 0;
} else if (arr.length == 1) {
return 1;
} else if (arr[index] != -1) {
contains = true;
for (int i = index + 1; i < arr.length; i++) {
if (arr[index] == arr[i]) {
arr[i] = -1;
}
}
}
return countDistinct(arr, index + 1) + (contains ? 1 : 0);
}
int numOfValues(int[] arr) {
boolean[] c = new boolean[10];
int count = 0;
for(int i =0; i < arr.length; i++) {
if(!c[arr[i]]) {
c[arr[i]] = true;
count++;
}
}
return count;
}
I have an array I have created that is a length of 25 and and has randomly generated numbers in it 1 to 25. The array will pretty much always have duplicate numbers in it and all i want to do is display the numbers that occur only once in the array. The code I have so far seems to work as long as the numbers that are repeated only repeat an even number of times. My question is how do I make this work so I only get numbers that occur once added to my string.
I can not use hash or set or anything like that this is part of an assignment.
int count2 = 0;
for (int d = 0; d < copy.length-1; d++)
{
int num = copy[d];
if (num != copy[d+1])
{
s = s + "," + num;
}
else
{
d++;
}
}
Use a HashSet!
Construct two new HashSets, one for the elements appearing just once and one for the duplicates
Iterate through your array
For each value in the array check if it's already in the set of duplicates. If so, do nothing else and continue to the next iteration
Check if the value is already in the set of elements appearing just once
If it's not, add it. If it is, remove it and add it to a list of duplicates
Call hashSet.toArray() and then you will have an array of all the elements appearing only once
You can convert the array to a string or use it however you wish
This approach is very efficient as search, insert, and remove are all O(1) in a HashSet.
I would start by writing a separate method to count the number of occurrences of a value in the given array so you can count how many occurrences there are for each value using a For-Each Loop like
private static int count(int[] arr, int value) {
int count = 0;
for (int item : arr) {
if (item == value) {
count++;
}
}
return count;
}
Then you can leverage that like
public static String toUniqueString(int[] arr) {
StringBuilder sb = new StringBuilder();
for (int value : arr) {
if (count(arr, value) == 1) {
if (sb.length() != 0) {
sb.append(", ");
}
sb.append(value);
}
}
return sb.toString();
}
Finally, to test it
public static void main(String[] args) {
Random rand = new Random();
int[] arr = new int[25];
for (int i = 0; i < arr.length; i++) {
arr[i] = rand.nextInt(arr.length) + 1;
}
System.out.println(toUniqueString(arr));
}
I tried to generate a sorted list of random data with no duplicates in descending order for my array. It also returns number of duplicates, but it keeps printing out nothing but zero .... Can anyone help me please :(
// 2. Ask the user for size of arbitrary numbers.
System.out.print("Please enter a size for arbitray numbers: ");
int size = indata.nextInt();
int [] SortedNumbers = new int [size];
// 3. Process arbitrary numbers and remove all duplicates
int numDuplicates = generate_data(SortedNumbers);
// 4. Print the numbers and number of duplicates
printArray(SortedNumbers, numDuplicates);
and here is the random method
public static int generate_data (int [ ] list){
int duplicates = 0;
Random random = new Random();
System.out.println(n[random.nextInt(n.length)]);
return duplicates;
}
here is the print_array method
public static void printArray(int [] list, int duplicates) {
// Additional code required
System.out.println("\nSize of array: " + list.length + " .Numbers of duplicates: " + duplicates); for (int i = 0; i<list.length; i++){
System.out.printf("%7d", list[i]);
if ((i + 1) % 10 == 0){
System.out.println();
}
}
}
random.nextInt(n.length)
gives you a random index of your array.
But printing the value corresponding to this index, will always give you 0. As you never store any other value in the array.
You should rather do something like this :
int[] list = new int[10];
int duplicates = 0;
Random random = new Random();
for (int i = 0; i < list.length; i++) {
int nextVal = random.nextInt(list.length);
System.out.println("list["+i+"] = "+ nextVal);
// test duplicates
for (int index = 0; index < i; index++) {
if (list[index] == nextVal) {
duplicates++;
break;
}
}
list[i] = nextVal;
}
return duplicates;
Your generate_data method always returns 0, since the local field duplicates is initialized with a 0 value and never changed.
The n field referenced by your generate_data method (which you haven't posted) is likely to be an int[], but its elements might not have been initialized (hence the print out will print default value 0, if within array index).
Hence your numDuplicates local field is always 0 too.
Notes
Your Random initialization is not performing. You should initialize a static Random object in your class and re-use it, instead of re-initializing every time in your generate_data method.
You probably want to have a look at coding conventions for Java in terms of field naming
You might want to post the code in your printArray method as well