I have the array of images with a length of 6 (we call array first).I want to save this 6 values in another array with a length of 12 so that each value of the first array repeated twice in the second array and the values placed in random places of the second array .
For example : first array = {3,4,20,33,1,25}
The second array can be = {4,20,33,1,20,25,25,3,4,1,3,33}
public class PlayActivity extends AppCompatActivity {
public static boolean isTheSameOk = true;
final Random rnd = new Random();
int saverandom;
int dontsame = 0 ;
int [] allimages = {R.drawable.img1, R.drawable.img2, R.drawable.img3, R.drawable.img4, R.drawable.img5,
R.drawable.img6, R.drawable.img7, R.drawable.img8, R.drawable.img9, R.drawable.img10, R.drawable.img11,
R.drawable.img12, R.drawable.img13, R.drawable.img14, R.drawable.img15, R.drawable.img16, R.drawable.img17,
R.drawable.img18, R.drawable.img19, R.drawable.img20, R.drawable.img21, R.drawable.img22, R.drawable.img23,
R.drawable.img24, R.drawable.img25, R.drawable.img26, R.drawable.img27, R.drawable.img28, R.drawable.img29,
R.drawable.img30, R.drawable.img31, R.drawable.img32, R.drawable.img33, R.drawable.img34, R.drawable.img35,
R.drawable.img36, R.drawable.img37, R.drawable.img38, R.drawable.img39, R.drawable.img40};
int [] chooseimages = new int [6];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play);
//choose 6 image from 40 image we have for putting into buttons
for(int counter = 0 ; counter<6 ; counter++){
saverandom = rnd.nextInt(39);
if(DontSameChoose(allimages[saverandom])){
chooseimages[counter] = saverandom;
}else {
counter--;
}
}
//put the select images in buttons
}
protected boolean DontSameChoose (int imageid){
for(int c = 0 ; c<6 ; c++){
if(imageid == chooseimages[c]){
isTheSameOk = false;
}
}
return isTheSameOk;
}
}
the first array is choose images that have the 6 id of the images and i want to save the values in the way i said above in the another array with the lenght of 12 .
If you transform your arrays into ArrayList, here is a short solution:
ArrayList<Integer> secondList = new ArrayList<>(firstList);
secondList.addAll(firstList);
Collections.shuffle(secondList);
Use this code
HashMap <Integer,Integer> mapa;
mapa = new HashMap<>();
int cont=0;
int arr[] = new int[12];
int arr2[] = new int[]{3,4,20,33,1,25};
for(int i=0;i<12;i++){
arr[i] = (int)Math.random()*100;
}
while(true){
int random = (int)Math.random()*12;
if(mapa.containsKey(random)){
}else{
mapa.put(random, 1);
arr[random] = arr2[cont++];
}
if(cont >= 6){
break;
}
}
Related
Ive written this java code how can i do the equivalent in objective c. Is this a correct approach of doing aa am new to objective c
public double[][] valuesR = new double[100][16];
public double[][] valuesIR = new double[100][16];
public int snrDataBufferSize = 0;
public String Test()
{
//ch1 ch2... are the the values in float
double[] channelValuesR = {ch1R, ch2R, ch3R, ch4R, ch5R, ch6R, ch7R, ch8R, ch9R, ch10R, ch11R, ch12R, ch13R, ch14R, ch15R, ch16R};
double[] channelValuesIR = {ch1IR, ch2IR, ch3IR, ch4IR, ch5IR, ch6IR, ch7IR, ch8IR, ch9IR, ch10IR, ch11IR, ch12IR, ch13IR, ch14IR, ch15IR, ch16IR};
if (snrDataBufferSize > 99){
//Reset buffer counter to 0
snrDataBufferSize = 0;
//Get signal SNR
getSNR();
}
else{
//Build double array values with 16 channels of value
valuesR[snrDataBufferSize] = channelValuesR;
valuesIR[snrDataBufferSize] = channelValuesIR;
//Iterate bufferSize counter
snrDataBufferSize++;
}
}
ive wriiten like this but am getting the error in building the double array value with 16 channels of value
double valuesR[100][16];
double valuesIR[100][16];
int snrDataBufferSize = 0;
-(void) Test {
double channelValuesR[] = {ch1R, ch2R, ch3R, ch4R, ch5R, ch6R, ch7R, ch8R, ch9R, ch10R, ch11R, ch12R, ch13R, ch14R, ch15R, ch16R};
double channelValuesIR[] = {ch1IR, ch2IR, ch3IR, ch4IR, ch5IR, ch6IR, ch7IR, ch8IR, ch9IR, ch10IR, ch11IR, ch12IR, ch13IR, ch14IR, ch15IR, ch16IR};
if (snrDataBufferSize > 99){
//Reset buffer counter to 0
snrDataBufferSize = 0;
}
else{
//Build double array values with 16 channels of value
valuesR[snrDataBufferSize] = channelValuesR;
valuesIR[snrDataBufferSize] = channelValuesIR;
//Iterate bufferSize counter
snrDataBufferSize++;
}
}
Is this a right way or is there any other way to do this
I'm making a card game, and I've arrived at the shufflin' time.
I've to shuffle a few cards (that are chosen before from the user, so they're not always the same amount) and then display them to the user one by one.
As I'm still developing the game's logic I'm displaying cards' name by changing a button text.
But I get stuck when I try to get the cards' name and set them as the button's text.
What happens is me gettin' a blank button or just with "Masons" or "Villager" String. Infact if I check the log I see that all the others cards(characters) get displayed as "null".
This is how I tried to achieve the goal (Yes I'm a newbie):
This is the head:
int demoniac;
int guard;
int masons;
int medium;
int mythomaniac;
int owl;
int villager;
int werehamster;
int all;
int i;
int t;
String[] characters = new String[24];
Button randomButton;
My method to addAll the cards(characters):
public void addAll(){
for(i = 0; i < all; i++){
add(demoniac, "Demoniac");
add(guard, "Guard");
add(medium, "Medium");
add(mythomaniac, "Mythomaniac");
add(owl, "Owl");
add(werehamster, "Werehamster");
add(villager, "Villager");
add(masons, "Masons");
}
}
My method to add and manage the various types of cards(characters):
public int add(int character, String name){
if(character != 0 && name == "Villager"){
for(t = 0; t < character; t++){
i+=t;
characters[i] = name;}
}
else if(character == 2 && name == "Masons"){
characters[i] = name;
i++;
characters[i] = name;
Toast.makeText(randomSelection.this, "works", Toast.LENGTH_SHORT).show();
}else if(character != 0){
characters[i] = name;
}
return i;
}
To randomize:
public void randomize(){
Collections.shuffle(Arrays.asList(characters));
for (int s = 1; s < characters.length; s++)
{
System.out.println(characters[s]);
}
}
The method to display a different card(character) each time the user clicks the button:
public void show(View view){
for (int s = 1; s < characters.length; s++)
{
randomButton.setText(characters[s]);
}
}
EDIT:
I've noticed the no sense for loop I've done, by the way you should know although most of the characters are only 1 of their kind (demoniac, guard, etc..) there are 2 Masons and from 5 to 12 Villagers, so We need to retrieve these ints and add as much Strings to the Array as much we're told from those ints.
Example: If I get 6 Villagers, I've to add the String "Villager" 6 times into the String Array.
Then I've set that s value to 1 'cause I've to display the first
String ([0]) as soon as the Activity gets started, so on the OnCreate() method.
Maybe I'm wrong, if so I please you to correct me!
Getting a blank button or just with "Masons" or "Villager" String
That is because you only set the Button's text with the last element of the list. Which is either null or "Masons" (not seeing how it could be "Villager").
for (int s = 1; s < characters.length; s++)
{
randomButton.setText(characters[s]);
}
If I check the log I see that all the others cards(characters) get displayed as "null"
You only set position 0 of your array. For example, you don't initialize the positions, so these int values default to 0.
int demoniac;
int guard;
int all;
Then
for(i = 0; i < all; i++){
add(demoniac, "Demoniac");
add(guard, "Guard");
Really, that loop shouldn't be entered because all equals 0.
Additionally
Collections are zero-indexed, so this doesn't print element 0. You need to set int s = 0;.
for (int s = 1; s < characters.length; s++)
It isn't clear to me what the add(int character, String name) method is returning, but if you explain it, I will update this answer.
I believe this code fulfills most of what you are trying to achieve
// Where the characters are stored
private ArrayList<String> characters;
public void initDeck() {
if (characters == null)
characters = new ArrayList<String>();
// Extract the numbers if you actually need them, otherwise, they just are constants
addCharacter("Demoniac", 1, characters);
addCharacter("Guard", 1, characters);
addCharacter("Medium", 1, characters);
addCharacter("Mythomaniac", 1, characters);
addCharacter("Owl", 1, characters);
addCharacter("Werehamster", 1, characters);
addCharacter("Villager", 5, characters);
addCharacter("Masons", 1, characters);
}
public void addCharacter(String name, int amount, ArrayList<String> cards) {
if (amount < 0) {
throw new IllegalArgumentException("Must add a non-negative number of characters for " + name);
}
// Don't use '==' for Strings
if (name.equals("Villager")) {
if (amount != 5 || amount != 12) {
throw new IllegalArgumentException("There can only be 5 or 12 " + name);
}
}
for (int i = 0; i < amount; i++) {
cards.add(name);
}
}
public int searchCharacters(String character, ArrayList<String> cards) {
return cards.indexOf(character);
}
public Map<String, Integer> getAllCharacterPositions() {
Map<String, Integer> allPositions = new LinkedHashMap<String, Integer>();
for (int i = 0; i < characters.size(); i++) {
allPositions.put(characters.get(i), i);
}
return allPositions;
}
void run() {
// initialize the characters
initDeck();
// shuffle them
Collections.shuffle(characters);
// print them all out
for (int i = 0; i < characters.size(); i++) {
System.out.printf("%d: %s\n", i, characters.get(i));
}
// Find the position of a character
System.out.println();
String findCharacter = "Owl";
// Option 1 -- always linear search lookup
System.out.printf("%d: %s\n", searchCharacters(findCharacter, characters), findCharacter);
// Option 2 -- one-time linear scan, constant lookup
Map<String, Integer> positions = getAllCharacterPositions();
System.out.printf("%d: %s\n", positions.get(findCharacter), findCharacter);
// Get a random character
System.out.println();
Random rand = new Random(System.currentTimeMillis());
int randPos = rand.nextInt(characters.size());
System.out.printf("%d: %s\n", randPos, characters.get(randPos));
// randomButton.setText(characters.get(randPos));
}
Given the array is already shuffled, just look at the first card:
public void show(View view){
randomButton.setText(characters[0]);
}
If you want to navigate that deck I suggest you put the shuffled list in to a Queue, where you can look at the next card (peek) or take the next card (poll):
private static Queue<string> buildNewShuffledDeck(String[] characters){
List<String> shuffledCharacterList = new ArrayList<String>(characters);
Collections.shuffle(shuffledCharacterList);
Queue<string> deck = new ArrayDeque(shuffledCharacterList);
return deck;
}
public void show(View view){
String nextCard = deck.peek();
if (nextCard != null)
randomButton.setText(nextCard);
else
//deck is empty...
}
Then to take from the deck, say on the random button click:
String nextCard = deck.poll();
General advice on arrays: Stop using them in favor of other data types that are far more useful and interchangeable.
Then next step advice, make a class that represents a Card and stop using Strings, the string you currently have is just one property of a card.
You are just displaying the last character name that you add
Replace with this
public void show(View view){
Random r = new Random(System.currentTimeMillis());
randomButton.setText(characters[r.nexInt(characters.length)])
}
I'm trying to build simple multithreading application. But I'm confused about Java monitors. I have many threads that want to format with their data one array. So for example I have Supermarket Threads (data of the thread is in txt file) So first thread have these product (Milk, Cheese, Chocolate) and country code for each product 1,2, 3
SupermarketA
Milk 1
Cheese 2
Chocolate 3
SupermarketB
Yogurt 1
Orangle 2
Bannana 3
Tea 7
Kiwi 9
and I want to format array that has to fields (country_code and count)
So my array should look like that
Country_code count
1 2
2 2
3 2
7 1
9 1
Code
public class SortedArray{
private int num = 0; // num is country code
private int count = 0;
}
So here's my monitor class
public class SingleArray {
private SortedArray[] array;
private int arrayIndex;
private static final int MAX_SIZE = 5;
public SingleArray() {
array = new SortedArray[MAX_SIZE];
arrayIndex = 0;
initArray();
}
private void initArray() {
for (int i = 0; i < MAX_SIZE; i++) {
array[i] = new SortedArray();
}
}
public synchronized void inc(){
awaitUnderMax();
notifyAll();
}
private void awaitUnderMin(){
while (arrayIndex == 0) try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void dec(){
awaitUnderMin();
notifyAll();
}
public void add(ArrayList<Integer> count){
for (int i = 0; i < count.size(); i++) {
singleArray.inc();
int num = count.get(i);
if (singleArray.arrayIndex == 0) { // if array is empty add value to it
singleArray.array[0].num = num;
singleArray.array[0].count++;
singleArray.arrayIndex++;
} else {
if (!isThere(num)) { // if num is a new value to array
singleArray.inc();
int index1 = singleArray.arrayIndex;
if (num > singleArray.array[index1 - 1].num) {
singleArray.inc();
singleArray.array[index1].num = num;
singleArray.inc();
singleArray.array[index1].count++;
singleArray.inc();
singleArray.arrayIndex++;
System.out.println(Thread.currentThread().getName() + " first " + singleArray.array[index1].num);
} else if (num < singleArray.array[index1 - 1].num) { // jei num mazesne uz paskutinia masyvo reiksme
int index = index1 - 1 < 0 ? index1 : index1 - 1;
while (index > 0 && num < singleArray.array[index].num) {
index--;
}
if (index != singleArray.arrayIndex) {
System.out.println(Thread.currentThread().getName() + " sec " + singleArray.array[index].num);
singleArray.array = addPos(singleArray.array, index + 1, num);
}
}
}
}
}
}
public boolean isThere(int number){
for(int i=0; i<singleArray.arrayIndex; i++){
singleArray.inc();
if(number == singleArray.array[i].num){
singleArray.array[i].count++;
return true;
}
}
return false;
}
private void awaitUnderMax(){
while (arrayIndex >= MAX_SIZE) try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void removeValue(int number, int howManyItems){
for(int i=0; i<arrayIndex; i++){
dec();
if(number == array[i].num){
int numberToDelete = array[i].count - howManyItems >= 0 ? howManyItems : array[i].count;
if(array[i].count >= numberToDelete){
array[i].count -= numberToDelete;
}
if(array[i].count == 0){
deleteItem(i);
}
}
if(array[i].count == 0){
deleteItem(i);
}
}
}
Each thread call add(ArrayList<Integer> count) method
So basically what add method does:
Find place where to insert new value (dependng if new value is greater or lower than a previous)
call isThere(int num) method that check if new value is already in array (if so increment count singleArray.array[i].count++) otherwise add new value to array
If array is full arrayIndex == MAX_SIZE wait current thread for other threads to decrement arrayIndex (this is oly one part of code I also have other threads that based on county code decrement array)
So the biggest problem is that multiplethreads need to update single array at the same time (I know that adding synchronized keyword to add method should solve this problem but it only let one thread to run this method at once!) So sometimes all works fine, but sometimes I get really starnge results (for example that country code is 0 (That is imposible!!!) and sometimes new values is placed in wrong array posiitons). Also I think that semaphores should solve this problem, but is it possible to do that with monitors? Thank's for the answers.
EDIT v2
to #Elyasin
public Thread[] setUpShopsBuilderThreads(){
int size = data.getSize();
ArrayList<ArrayList<String>> a = new ArrayList<>();
ArrayList<ArrayList<Integer>> b = new ArrayList<>();
ArrayList<ArrayList<Double>> c = new ArrayList<>();
Thread[] threads = new Thread[size];
for (int i = 0; i < size; i++) {
int tmp = data.getIndex(i);
int range = i + 1 < size ? data.getIndex(i + 1) : data.getWaresSize();
ArrayList<String> name = new ArrayList<>();
ArrayList<Integer> count = new ArrayList<>();
ArrayList<Double> price = new ArrayList<>();
for (int j = tmp; j < range; j++) {
name.add(data.getName(j));
count.add(data.getCount(j));
price.add(data.getPrice(j));
}
a.add(name);
b.add(count);
c.add(price);
}
procesas_1 p1 = new procesas_1(a.get(0), b.get(0), c.get(0));
procesas_2 p2 = new procesas_2(a.get(1), b.get(1), c.get(1));
procesas_3 p3 = new procesas_3(a.get(2), b.get(2), c.get(2));
procesas_4 p4 = new procesas_4(a.get(3), b.get(3), c.get(3));
procesas_5 p5 = new procesas_5(a.get(4), b.get(4), c.get(4));
Thread worker1 = new Thread(p1);
Thread worker2 = new Thread(p2);
Thread worker3 = new Thread(p3);
Thread worker4 = new Thread(p4);
Thread worker5 = new Thread(p5);
threads[0] = worker1;
threads[1] = worker2;
threads[2] = worker3;
threads[3] = worker4;
threads[4] = worker5;
return threads;
}
public static void main(String[] args) {
Starter start = new Starter();
start.read();
start.printShopsData();
start.printUserData();
Thread[] builderThreads = start.setUpShopsBuilderThreads();
for(int i=0; i<builderThreads.length; i++){
builderThreads[i].start();
}
}
what about using the concurrent safe datasets java already provides?
if you want it sorted, this one looks it might work for you:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentSkipListSet.html
just add it as in a normal Collection
I have 2 list, an array for imageviews and an array for the drawables :
List<Integer> imageViews = new ArrayList<Integer>();
List<Integer> images = new ArrayList<Integer>();
Here is where I add items in each list.
public void viewadd()
{
imageViews.add(R.id.star1);
imageViews.add(R.id.star2);
imageViews.add(R.id.star3);
imageViews.add(R.id.star4);
imageViews.add(R.id.star5);
imageViews.add(R.id.star6);
imageViews.add(R.id.star7);
imageViews.add(R.id.star8);
imageViews.add(R.id.star9);
imageViews.add(R.id.star10);
imageViews.add(R.id.star11);
imageViews.add(R.id.star12);
}
public void imageadd()
{
images.add(R.drawable.blue);
images.add(R.drawable.red);
images.add(R.drawable.green);
images.add(R.drawable.violet);
images.add(R.drawable.orange);
images.add(R.drawable.yellow);
images.add(R.drawable.blue);
images.add(R.drawable.red);
images.add(R.drawable.green);
images.add(R.drawable.violet);
images.add(R.drawable.orange);
images.add(R.drawable.yellow);
}
Now when I click on a specific star (or could be in the onCreate method), it should be randomized accordingly.
Random drawable in a random imageview :
View.OnClickListener tapHandler = new View.OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
imageadd();
viewadd();
Random rng = new Random();
List<Integer> generated = new ArrayList<Integer>();
for (int i = 0; i < 12; i++)
{
while(true)
{
Integer next = rng.nextInt(imageViews.size()) ;
if (!generated.contains(next))
{
generated.add(next);
ImageView iv = (ImageView)findViewById(imageViews.get(next));
iv.setImageResource(images.get(next));
images.remove(next);
imageViews.remove(next);
break;
}
}
}
}
};
And so I want to know what was the last drawable used inside the for loop so I can set tag in it?
Just keep a reference to the last ImageView outside the loop.
// last image reference
Drawable lastImg = null;
List<Integer> generated = new ArrayList<Integer>();
for (int i = 0; i < 12; i++) {
while (true) {
Integer next = rng.nextInt(imageViews.size());
if (!generated.contains(next)) {
generated.add(next);
ImageView iv = (ImageView) findViewById(imageViews
.get(next));
iv.setImageResource(images.get(next));
// skip when i = 0
if (lastImg != null) {
iv.setTag(lastImg); // tag the last drawable
}
// store the current drawable
lastImg = getResources().getDrawable(images.get(next));
images.remove(next);
imageViews.remove(next);
break;
}
}
}
And, unless it serves some other purpose, you could also probably call imageadd() and viewadd() only once, and not on every onClick(). You would just have to skip calling images.remove() and imageViews.remove() from inside your loop then.
I've a piece of code something like this and I want to insert the data by using a while.
Weather weather_data[] = new Weather[]{
new Weather(0, "Cloudy"),
new Weather(0, "Showers"),
new Weather(0, "Snow"),
new Weather(0, "Storm"),
new Weather(0, "Sunny")
};
How can I fill this list using a while ?
Thanks
Try this:
Weather weather_data[] = new Weather[5];
int i = 0;
while(i < weather_data.length){
//fill array [i]
i++;
}
I understand that you want to fill your array with the following String array as base:
String[] weatherTypes = {"Cloudy","Showers","Snow","Storm","Sunny"};
Then you can do this:
int i=0;
Weather[] weather_data = new Weather[];
for (String weatherType: weatherTypes){
weather_data[i] = new Weather(0,weatherType);
i++;
}
You could use also use a list:
List<Weather> weather_data = new ArrayList<Weather>();
for (String weatherType: weatherTypes){
weather_data.add(new Weather(0,weatherTypes));
}
Weather[] weather_data = new Weather[5];
public void addWeatherData(Weather newWeather) {
int counter = 0;
while (counter < weather_data.length) {
if (weather_data[counter] == null) {
weather_data[counter] = newWeather;
return;
}
counter++;
}
}