Weird Output in the Main Method - arrays

I need to generate 5 + 1 UNIQUE random numbers and store them into array which is then returned. Here's my code
public static int[] drawNumbers(int number)
{
int[] unique = new int[7];
int x = 0;
int y = 0;
while(x < unique.length)
{
unique[x] = (int)(Math.random()*45+1);
while(y < x)
{
if(unique[x] == unique[y])
{
x--;
break;
}
y++;
}
x++;
}
return unique;
}
I don't know what's wrong with my code but when I do this in the main method:
System.out.print(drawNumbers(parameter) + " ");
I get outputs like this:
" [I#4a5e88f7 "

drawNumbers returns an array of integers, but System.out.print can't print out an entire array. Instead, you need to print each item seperately, like so:
for (int x : drawNumbers(parameter)) {
System.out.print(x + " ");
}

Related

Comparison between pointer (char*) and integer error

So basically the user inputs how many countries they have visited in a variable, then I take it as the size of the array.
After that I use a for loop to list out all the countries visited. But I want to make my code a little smarter and put and at the end of the sentence for the final country.
For example 3 countries:
You visited Japan, Korea and Canada.
^ ^^^
#include <stdio.h>
#include <cs50.h>
int main(void)
{
int number_of_p = get_int("How many countries did you visit?\n");
string countries[number_of_p];
for (int x = 0; x < number_of_p; x++)
{
countries[x] = get_string("What countries did you visit?\n");
}
printf("You visited %i countries, including: ", number_of_p);
for (int x = 0; x < number_of_p; x++)
{
printf("%s, ", countries[x]);
/* looks for last element in arrays, inserts 'and'
to make it look grammatically correct. */
if (countries[x] == number_of_p - 1 ) // ERROR HERE
{
printf(" and ");
}
}
printf(".\n");
}
I'm getting a comparison between pointer (char*) and integer error.
What does char* mean?
How do I access the last element in an array?
countries[x] is a string (which in CS50 is a typedef of char*), number_of_p is an int, you can't compare them, they are different types, you may have wanted to compare the index x, a possible (and quick) fix for your code, including the punctuation could look like this:
Live demo
#include <stdio.h>
#include <cs50.h>
int main(void)
{
int number_of_p = get_int("How many countries did you visit?\n");
string countries[number_of_p];
for (int x = 0; x < number_of_p; x++)
{
countries[x] = get_string("What countries did you visit?\n");
}
printf("You visited %i countries, including: ", number_of_p);
for (int x = 0; x < number_of_p; x++)
{
printf("%s", countries[x]);
if(x < number_of_p - 2){
printf(", ");
}
if (x == number_of_p - 2)
{
printf(" and ");
}
}
printf(".\n");
}
Input:
3
Japan
Korea
Canada
Output:
You visited 3 countries, including: Japan, Korea and Canada.
The condition in the if statement
if (countries[x] == number_of_p - 1 )
does not make a sense. The left operand countries[x] has the type char * while the right operand has the type int.
That is the type specifier string is an alias for the type char * and this declaration of an array
string countries[number_of_p];
is the same as
char * countries[number_of_p];
So you have an array of pointers that point to strings.
The alias string for the type char * in C defined the following way
typedef char * string;
The loop can look like
for (int x = 0; x < number_of_p; x++)
{
if ( x != 0 )
{
putchar( ',' );
putchar( ' ' );
if ( x == number_of_p - 1 )
{
printf( "%s ", "and " );
}
}
printf("%s", countries[x]);
}
Here is a demonstrative program
#include <stdio.h>
int main(void)
{
enum { number_of_p = 3 };
char *countries[number_of_p] =
{
"Japan", "Korea", "Canada"
};
printf( "You visited %i countries, including: ", number_of_p );
for (int x = 0; x < number_of_p; x++)
{
if ( x != 0 )
{
putchar( ',' );
putchar( ' ' );
if ( x == number_of_p - 1 )
{
printf( "%s ", "and" );
}
}
printf("%s", countries[x]);
}
return 0;
}
Its output is
You visited 3 countries, including: Japan, Korea, and Canada
You can do this sort of thing with one printf, using a predefined string for the separator. Using a single printf rather than special casing the tail of the list is generally easier to maintain. Many people find the ternary operator confusing; here's the approach in two different ways, using a switch first and the ternary operator second:
#include<stdio.h>
int main(void)
{
char *countries[] = { "foo", "bar", "baz" };
int number_of_p = sizeof countries / sizeof *countries;
/* First loop, using a switch */
for( int x = 0; x < number_of_p; x++ ) {
char *div = ", ";
switch( x ){
case sizeof countries / sizeof *countries - 2: div = ", and "; break;
case sizeof countries / sizeof *countries - 1: div = ".\n"; break;
}
printf("%s%s", countries[x], div);
}
/* Same loop as above, with if/else instead of the switch */
for( int x = 0; x < number_of_p; x++ ) {
char *div = ", ";
if( x == number_of_p - 2 ) {
div = ", and ";
} else if( x == number_of_p - 1 ) {
div = ".\n";
}
printf("%s%s", countries[x], div);
}
/* Same loop as above, written less verbosely */
for( int x = 0; x < number_of_p; x++ ) {
printf("%s%s", countries[x], x == number_of_p - 2 ? ", and " :
x == number_of_p - 1 ? ".\n" : ", ");
}
}

How do I get the integer method "guess" to go into another method as an array?

else {
masterNum[3] = guess % 10; //checks integers in their respective positions
masterNum[2] = ((guess - guess%10)/10)%10;
masterNum[1] = ((guess - guess % 100)/100)%10;
masterNum[0] = (guess - guess % 1000)/1000;
masterDigit(guess, masterNum);
}
//}
//This method determines the total number of correct digits but not
//necessarily in the correct position
public static int masterDigit (int [] guess,int [] code) //int [] guess
{
int i,j,k,number;
int [] tempGuess = new int [4]; //an array to hold a copy of a code
boolean found;
number = 0;
for(k=0; k<4; k++) //copies code to tempGuess so code
//doesn't get changed (you can't just assign code to tempGuess)
tempGuess[k] = code[k];
for(i = 0; i < 4; i++)
{
j=0;
found = false;
while(j < 4 && found == false) // a while loop instead of a
// for loop so duplicates are only counted once
{
if(guess[i] == tempGuess[j])
{
found = true;
tempGuess[j] = -1; // fills up tempGuess with an impossible
// value so that index only gets
// counted once
number++;
}
j++;
}
}
return number;
}
This code is for a Mastermind game with integers. Upon running through the compiler, there is an error saying that integer "guess" cannot be converted to an array. How can I get my guess (defined as an integer scanner console) to go into this method that will check which numbers are correct?

How do I generate A-Z randomly to fill an array?

My assignment is to create a 3 part program which when you press 1, it runs method or "feature" 1, when you press 2, it runs feature 2, press 3, it runs feature 3. The end. I have the second feature figured out, but this feature (feature 1) is supposed to generate A-Z randomly to fill a 10x20 array. The code AS IS generates random integers and correctly fills and DISPLAYS a 10 x 20 grid. HOWEVER, how do I get it to display A-Z characters instead of numbers?
public class ModuleOnefor8 {
public static void main(String[] args) {
int[][] matrix = new int[10][20];
for (int i=0; i<matrix.length; i++) {
for (int j = 0; j<matrix[i].length; j++) {
matrix[i][j] = (int)(Math.random()*'Z'-'A' + 1);
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}
}
Add:
public static String numberToAlpha(int number)
{
char[] ls = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
String r = "";
while(true)
{
r = ls[number % 26] + r;
if(number < 26) {
break;
}
number /= 26;
}
return r;
}
Use:
int min_int = 1;
int max_int = 9999;
string out_alpha = MyClass.numberToAlpha( Math.random() * ( max_int - min_int ) + min_int );

Algorithm to iterate N-dimensional array in pseudo random order

I have an array that I would like to iterate in random order. That is, I would like my iteration to visit each element only once in a seemingly random order.
Would it be possible to implement an iterator that would iterate elements like this without storing the order or other data in a lookup table first?
Would it be possible to do it for N-dimensional arrays where N>1?
UPDATE: Some of the answers mention how to do this by storing indices. A major point of this question is how to do it without storing indices or other data.
I decided to solve this, because it annoyed me to death not remembering the name of solution that I had heard before. I did however remember in the end, more on that in the bottom of this post.
My solution depends on the mathematical properties of some cleverly calculated numbers
range = array size
prime = closestPrimeAfter(range)
root = closestPrimitiveRootTo(range/2)
state = root
With this setup we can calculate the following repeatedly and it will iterate all elements of the array exactly once in a seemingly random order, after which it will loop to traverse the array in the same exact order again.
state = (state * root) % prime
I implemented and tested this in Java, so I decided to paste my code here for future reference.
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
public class PseudoRandomSequence {
private long state;
private final long range;
private final long root;
private final long prime;
//Debugging counter
private int dropped = 0;
public PseudoRandomSequence(int r) {
range = r;
prime = closestPrimeAfter(range);
root = modPow(generator(prime), closestPrimeTo(prime / 2), prime);
reset();
System.out.println("-- r:" + range);
System.out.println(" p:" + prime);
System.out.println(" k:" + root);
System.out.println(" s:" + state);
}
// https://en.wikipedia.org/wiki/Primitive_root_modulo_n
private static long modPow(long base, long exp, long mod) {
return BigInteger.valueOf(base).modPow(BigInteger.valueOf(exp), BigInteger.valueOf(mod)).intValue();
}
//http://e-maxx-eng.github.io/algebra/primitive-root.html
private static long generator(long p) {
ArrayList<Long> fact = new ArrayList<Long>();
long phi = p - 1, n = phi;
for (long i = 2; i * i <= n; ++i) {
if (n % i == 0) {
fact.add(i);
while (n % i == 0) {
n /= i;
}
}
}
if (n > 1) fact.add(n);
for (long res = 2; res <= p; ++res) {
boolean ok = true;
for (long i = 0; i < fact.size() && ok; ++i) {
ok &= modPow(res, phi / fact.get((int) i), p) != 1;
}
if (ok) {
return res;
}
}
return -1;
}
public long get() {
return state - 1;
}
public void advance() {
//This loop simply skips all results that overshoot the range, which should never happen if range is a prime number.
dropped--;
do {
state = (state * root) % prime;
dropped++;
} while (state > range);
}
public void reset() {
state = root;
dropped = 0;
}
private static boolean isPrime(long num) {
if (num == 2) return true;
if (num % 2 == 0) return false;
for (int i = 3; i * i <= num; i += 2) {
if (num % i == 0) return false;
}
return true;
}
private static long closestPrimeAfter(long n) {
long up;
for (up = n + 1; !isPrime(up); ++up)
;
return up;
}
private static long closestPrimeBefore(long n) {
long dn;
for (dn = n - 1; !isPrime(dn); --dn)
;
return dn;
}
private static long closestPrimeTo(long n) {
final long dn = closestPrimeBefore(n);
final long up = closestPrimeAfter(n);
return (n - dn) > (up - n) ? up : dn;
}
private static boolean test(int r, int loops) {
final int array[] = new int[r];
Arrays.fill(array, 0);
System.out.println("TESTING: array size: " + r + ", loops: " + loops + "\n");
PseudoRandomSequence prs = new PseudoRandomSequence(r);
final long ct = loops * r;
//Iterate the array 'loops' times, incrementing the value for each cell for every visit.
for (int i = 0; i < ct; ++i) {
prs.advance();
final long index = prs.get();
array[(int) index]++;
}
//Verify that each cell was visited exactly 'loops' times, confirming the validity of the sequence
for (int i = 0; i < r; ++i) {
final int c = array[i];
if (loops != c) {
System.err.println("ERROR: array element #" + i + " was " + c + " instead of " + loops + " as expected\n");
return false;
}
}
//TODO: Verify the "randomness" of the sequence
System.out.println("OK: Sequence checked out with " + prs.dropped + " drops (" + prs.dropped / loops + " per loop vs. diff " + (prs.prime - r) + ") \n");
return true;
}
//Run lots of random tests
public static void main(String[] args) {
Random r = new Random();
r.setSeed(1337);
for (int i = 0; i < 100; ++i) {
PseudoRandomSequence.test(r.nextInt(1000000) + 1, r.nextInt(9) + 1);
}
}
}
As stated in the top, about 10 minutes after spending a good part of my night actually getting a result, I DID remember where I had read about the original way of doing this. It was in a small C implementation of a 2D graphics "dissolve" effect as described in Graphics Gems vol. 1 which in turn is an adaption to 2D with some optimizations of a mechanism called "LFSR" (wikipedia article here, original dissolve.c source code here).
You could collect all possible indices in a list and then remove a random indece to visit. I know this is sort of like a lookup table, but i don't see any other option than this.
Here is an example for a one-dimensional array (adaption to multiple dimensions should be trivial):
class RandomIterator<T> {
T[] array;
List<Integer> remainingIndeces;
public RandomIterator(T[] array) {
this.array = array;
this.remainingIndeces = new ArrayList<>();
for(int i = 0;i<array.length;++i)
remainingIndeces.add(i);
}
public T next() {
return array[remainingIndeces.remove((int)(Math.random()*remainingIndeces.size()))];
}
public boolean hasNext() {
return !remainingIndeces.isEmpty();
}
}
On a side note: If this code is performance relevant, this method would perform worse by far, as the random removing from the list triggers copies if you use a list backed by an array (a linked-list won't help either, as indexed access is O(n)). I would suggest a lookup-structure (e.g. HashSet in Java) that stores all visited indices to circumvent this problem (though that's exactly what you did not want to use)
EDIT: Another approach is to copy said array and use a library function to shuffle it and then traverse it in linear order. If your array isn't that big, this seems like the most readable and performant option.
You would need to create a pseudo random number generator that generates values from 0 to X-1 and takes X iterations before repeating the cycle, where X is the product of all the dimension sizes. I don't know if there is a generic solution to doing this. Wiki article for one type of random number generator:
http://en.wikipedia.org/wiki/Linear_congruential_generator
Yes, it is possible. Imagine 3D array (you not likely use anything more than that). This is like a cube and where all 3 lines connect is a cell. You can enumerate your cells 1 to N using a dictionary, you can do this initialization in loops, and create a list of cells to use for random draw
Initialization
totalCells = ... (xMax * yMax * zMax)
index = 0
For (x = 0; x < xMax ; x++)
{
For (y = 0; y < yMax ; y++)
{
For (z = 0; z < zMax ; z++)
{
dict.Add(i, new Cell(x, y, z))
lst.Add(i)
i++
}
}
}
Now, all you have to do is iterate randomly
Do While (lst.Count > 0)
{
indexToVisit = rand.Next(0, lst.Count - 1)
currentCell = dict[lst[indexToVisit]]
lst.Remove(indexToVisit)
// Do something with current cell here
. . . . . .
}
This is pseudo code, since you didn't mention language you work in
Another way is to randomize 3 (or whatever number of dimensions you have) lists and then just nested loop through them - this will be random in the end.

datatypes and arrays in java

Thoroughly confused on how to do this. What I want to do is to place the city with the lowest min, or max in the output. My understanding is you cannot throw a string in with another datatype in a method. How in the world can I match the name with the lowest temperature?
Lets say I want 3 cities:
I want to make the array 3 then:
Then I will add in the following cities, (Alanta, New York, Richmond)
The cities temperatures are (42.2, 98.8, -12.4)
Min is -12.4
Max is 98.8
That I have, how do I link Richmond's String that is stored in array[2] to temperature's double that is stored in array[2]? Any help is much appreciated.
import javax.swing.JOptionPane;
import java.util.Scanner;
import java.lang.Math;
public class Ex9
{
public static void main(String[] args)
{
String message ="";
double min = 0, max = 0, avg = 0;
int counter = 1;
int numberOfCities = Integer.parseInt(JOptionPane.showInputDialog(null, "How many cities would you like to enter?"));
String[] nameOfCities = new String[numberOfCities];
double[] temperatureOfCities = new double[numberOfCities];
for (int i = 0; i < nameOfCities.length; i++)
{
nameOfCities[i] = JOptionPane.showInputDialog(null, "Please enter the name of city " +counter+" :");
temperatureOfCities[i] = Double.parseDouble(JOptionPane.showInputDialog(null, "Please enter the current temperature of the city " + counter +" :"));
message += "City name " + nameOfCities[i] + ".\n"
+ "Temperature of city " + temperatureOfCities[i] + " is degrees\n";
counter++;
}//end numberOfCities loop
if(
JOptionPane.showMessageDialog(null, message + "\nThe average temperature is " +findAvg(temperatureOfCities)+ "\n[Name of city] has the lowest temperature, which is " + findMin(temperatureOfCities) + "\n[Name of city] has the highest temperature, which is " + findMax(temperatureOfCities));
}//end main
public static double findAvg(double[] temperatureOfCities)
{
double sum =0;
for(int i=0;i<temperatureOfCities.length;i++)
{
sum += temperatureOfCities[i];
}
sum = sum/temperatureOfCities.length;
return sum;
}//end findAvg
public static double findMin(double[] temperatureOfCities)
{
double min=0;
for(int i =0; i <temperatureOfCities.length;i++)
{
if (temperatureOfCities[i] <= temperatureOfCities[0])
{
min = temperatureOfCities[i];
}
}//end for loop
return min;
}//end findMin
public static double findMax(double[] temperatureOfCities)
{
double max=0;
for(int i =0; i <temperatureOfCities.length;i++)
{
if (temperatureOfCities[i] >= temperatureOfCities[0])
{
max = temperatureOfCities[i];
}
}//end for loop
return max;
}//end findMax
}//end program
Two main approaches here:
1) The procedural approach - just pass both arrays around instead of just one array. If they're kept synchronized there's no problem - just use the same index for both.
2) The object oriented approach - Define a class TemperatureReading with double temperature and string cityName. Then you can make a TemperatureReading[] array and pass it around, and the data is naturally associated.
Change your findMin, findAvg, and findMax methods to return a composite Measurement object.
class Measurement {
final double temperature;
final String cityName;
Measurment(String cityName, double temperature)
{
this.temperature = temperature;
this.cityName = cityName;
}
}
The updated methods could look something like this:
public static Measurement findMax(String[] nameOfCities, double[] temperatureOfCities) {
double maxTemp=0;
String maxName=null;
for(int i =0; i <temperatureOfCities.length;i++)
{
if (temperatureOfCities[i] >= temperatureOfCities[0])
{
maxTemp = temperatureOfCities[i];
maxName = nameOfCities[i];
}
} //end for loop
return new Measurement(maxTemp, maxName);
}
Now you can use the results like this:
Measurement maxMeasurement = findMax(nameOfCities, temperatureOfCities);
System.out.println(maxMeasurement.cityName + "has a temperature of " + maxMeasurement.temperature);
Similar goes for findMin and findAvg.

Resources