Can anyone provide me with a help about how can I map containers?
For example if I a have text file, which I import, and as the code reads trough the file it needs to map the lines which start with the same value (for example 1).
So how can I check if that line exists and if it does then import it the table, if not make a new record. And so on ...
If code sample or anything else is needed, please ask!
If you use a TextIO to read a file record per record, you'll get a container for each line.
A container is a structure you can refer as a super array. It will allow you to store anything at each position of this array (string, int, object, etc...) regardless what's store in the rest of the container.
There are two ways get and set data in it. There are functions (https://msdn.microsoft.com/en-us/library/aa570072.aspx) or you can use brackets:
ItemId itemId;
Qty qty;
Price price;
Container c;
//Add two elements in the container
c = ["1001", 10];
//Add a third element at the end
c += [1.5];
//Get the elements
[itemId, qty, price] = c;
So, it's a really versatile tool and it comes with a price. You can't manipulate it as a map or other collection classes.
Finally, the TexIO.read() method will get a container at each line, so you need to deal with it at each time. If you have a record identifier, a key and then data, it could be something like:
Container c;
TextIO file;
Map map = new Map(Types::Integer, Types::Container);
int identifier, key;
[...]
c = file.read();
while (c)
{
[identifier, key] = c;
if (identifier == 1 && !map.exists(key))
{
map.insert(key, c);
}
c = file.read();
}
Related
I'm working on a console program that allows to search in an array of a structure named Person
For simplicity I'm now assuming that all of the attributes are integers.
typedef struct Person {
int name;
int city;
int email;
} Person;
so the comparing function would look like this:
int comparing(int x, int y) {
return x == y;
}
I'm trying to make a searching function that would allow the user to use comparing(int x, int y) and the user can search using one or more criteria. Meaning they can search by just name and email for example.
If you want to have "checkboxes" that the user can check by moving the cursor on the screen with the arrow keys and then press the ENTER key to activate them, then you cannot do this with the C standard library, but you probably can do it with a platform-specific API. For example, if you are on the Linux platform, you can use ncurses. However, you might be better off creating a proper graphical application, i.e. not a console applicaton.
If you want to keep it a simple text console application using only the features of the C standard library, then you can have a text menu in which the user can specify that he wants to toggle a checkbox, and then it asks the user which checkbox number he wants to toggle. After every change of the checkboxes, the program reprints all checkboxes to show the user the new state of the checkboxes.
In the comments section, you specifically asked for code to show you how the loop of the search should look like. Therefore, I have written such a loop for you.
This loop requires that a variable of type struct Person with the name lf (which stands for "looking for") is created and filled with all search criteria. Only the fields that are actually being searched for have to be set. The remaining fields can stay uninitialized. Also, three variables of type bool must be created with the names should_match_name, should_match_city and should_match_email. These three variables must be set to specify whether to search for the corresponding field, and if set to true, the corresponding field must also be set in the lf variable. Note that you must #include <stdbool.h> to enable support for the bool variable type.
The loop could then look like this:
for ( int i = 0; i < number_of_valid_elements_in_array; i++ )
{
if (
( !should_match_name || lf.name == array[i].name ) &&
( !should_match_city || lf.city == array[i].city ) &&
( !should_match_email || lf.email == array[i].email )
)
{
printf(
"Matching person found:\nName: %d\nCity: %d\nE-Mail: %d\n\n",
array[i].name, array[i].city, array[i].email
);
}
}
Note that more sophisticated search algorithms (for example those used in database engines) do not search all elements in order to find a match, but they rather search using indexes. This makes the search significantly faster. These indexes would have to be created in advance, though. But as long as you have less than a million elements, it will probably not matter.
I am using as3 in adobe animate to create a video game.
I have created multiple arrays with movie clips e.g.
var A:Array [mc1, mc2, mc3]
var B:Array [mc4, mc5, mc6]
var C:Array [mc7, mc8, mc9]
var anObject:DisplayObject;
How can I operate all movie clips in all arrays simultaneously?
I have tried this:
mc_Player.addEventListener(MouseEvent.CLICK, Change_Position);
function Change_Position (event:MouseEvent):void
{
{for each (anObject in A) & (anObject in B) & (anObject in C) // how can I get this right?
{anObject.x -= 100;
}}
}
I am also trying to understand if there is a way to operate all movie clips in my project simultaneously without using arrays.
e.g.
mc_Player.addEventListener(MouseEvent.CLICK, Change_Position);
function Change_Position (event:MouseEvent):void
{
{all movie_clips // how can I get this right?
{anObject.x -= 100;
}}
}
Thank you.
There's no such thing as simultaneous in programming (well, unless you are multi-threading with the perfect sync, which is not an AS3 story at all).
There are to ways to get close to that simultaneous thing:
Put all the objects into a single container. You will be able to change x and y of that container so all the in-laid objects will change their visible positions at once. The downside is that you cannot rotate or scale them individually (think of them as clipped to a board and imagine you rotate the whole board), or you won't be able to move half of them.
Arrays and loops. You iterate through all the items one by one, very fast. It looks simultaneous from the outside, but it never is.
All that said, in order to achieve the things you want you need to figure a way to put all the objects you want to process simultaneously into a single Array and then do the thing you want on them.
Case №1: many Arrays to one.
// This methods takes a mixed list of items and Arrays
// and returns a single flattened list of items.
function flatten(...args:Array):Array
{
var i:int = 0;
// Iterate over the arguments from the first and on.
while (i < args.length)
{
if (args[i] is Array)
{
// These commands cut the reference to the Array
// and put the whole list of its elements instead.
aRay = [i,1].concat(args[i]);
args.splice.apply(args, aRay);
}
else
{
// The element is not an Array so let's just leave it be.
i++;
}
}
return args;
}
Then all you need to do is to get a single list out of your several Arrays:
var ABC:Array = flatten(A, B, C);
for each (var anObject:DisplayObject in ABC)
{
anObject.x -= 100;
}
Performance-wise, it is a good idea to pre-organize, if logically possible, these Arrays so you don't have to compile them each time you need to process all the objects. Simply, if sometimes you would need A + B, and sometimes B + C, and sometimes A + B + C, just create them and have them ready. If you know what you are going to deal with, you won't even need that complicated flatten method:
var AB:Array = A.concat(B);
var BC:Array = B.concat(C);
var ABC:Array = A.concat(B).concat(C);
Case №2: all the children at once. As I already explained in my answer to one of your previous questions, you can iterate over all the children of a certain container, and you can put them into — guess what — Array for later use. Also, you can filter the objects while doing so and put only those ones you actually want to be there.
var ALL:Array = new Array;
// Iterate over the amount of children of "this" container.
for (var i:int = 0; i < numChildren; i++)
{
// Obtain a reference to the child at the depth "i".
var anObject:DisplayObject = getChildAt(i);
// Here go possible criteria for enlisting.
// This will ignore texts and buttons.
// if (anObject is MovieClip)
// This will take only those with names starting with "mc".
if (anObject.name.substr(0, 2) == "mc")
{
ALL.push(anObject);
}
}
// Viola! You have all the objects you want in a single Array
// so you can bulk-process them now, which is ALMOST simultaneous.
I'm having a hard time in realizing how to use the repeated field rule.
for example, this is my .proto:
message Test
{
repeated float value = 1;
}
now, I'm initialize a new Test object:
Test test = test_init_zero()
Finally, I want to assign some values. For example:
float values[] = { 1.0, 2.2, 5.5, 7.13 }
My question is how can I assign them?
is it like
test.value = values
//or
test.value[0] = values[0] //... etc.
and then, how do I read them back?
This depends on how you define the repeated field inside the proto file. According to nanopb docs, you either just specify the repeated field like you did, and then use a callback function to handle each item separately during encoding/decoding, or you use nanopb-specific settings so have a fixed length array:
Strings, bytes and repeated fields of any type map to callback functions by default.
If there is a special option (nanopb).max_size specified in the .proto file, string maps to null-terminated char array and bytes map to a structure containing a char array and a size field.
If (nanopb).fixed_length is set to true and (nanopb).max_size is also set, then bytes map to an inline byte array of fixed size.
If there is a special option (nanopb).max_count specified on a repeated field, it maps to an array of whatever type is being repeated. Another field will be created for the actual number of entries stored.
For example, byte arrays need to use max_size:
required bytes data = 1 [(nanopb).max_size = 40, (nanopb).fixed_length = true];
And this would create the following field, when compiled using nanopb:
// byte arrays get a special treatment in nanopb
pb_byte_t data[40];
Or, for a float, you would use max_count according to rule 4.:
repeated float data = 1 [(nanopb).max_count = 40];
And then you'll get:
size_t data_count;
float data[40];
If you simply define a repeated field like you did, then nanopb will create a callback function:
// repeated float value = 1;
pb_callback_t value;
Which means you will have to provide your own function which will handle each incoming item:
yourobject.value.arg = &custom_args;
yourobject.value.funcs.decode = custom_function_for_decoding;
I have a program that allows the user to enter text, and it will highlight any repeat words. It already adds repeated words to one list and all the words to another. I want the program to print out the words, and if a repeat word is used, to highlight it.
I have tried using outputBox.Find(repeatList[i]) with a loop, but this only finds the first word used in the text. I also tried marking the current number for the last letter typed, selecting that point, finding the coordinates after the word.Length was typed, and then changing the colour of that, which didn't work.
for (int h = 0; h < repeatList.Count; h++)
{
for (int c = 0; c < repeatList.Count; c++)
{
outputBox.Find(repeatList[h]);
outputBox.SelectionColor = Color.Red;
}
}
At this point in the code, the outputBox already contains the users input, I just want to know how to compare words and select them for colouring. I've only just started Winforms and have only been coding for a few weeks, so I am sorry - I have looked at other answers but was not able to implement them. Thank you in advance for any responses.
EDIT: I would just like to add that my prefered method for colouring the text would be as it prints each word out, this was my original intention as I'm much more used to console applications where I can just change the colour and print more. If that method is easier to do than checking afterwards, I'm find to do that.
I would use the start index and keep a copy of it.
int startFrom = 0
...
startFrom = outputBox.Find(repeatList[h], startFrom)
You could then use the 'startFrom' index with the text word length to select the text.
Here is an example:
var findText = "test";
int index = 0;
do
{
index = richTextBox1.Find(findText, index, RichTextBoxFinds.WholeWord);
if (index > -1)
{
richTextBox1.Select(index, findText.Length);
richTextBox1.SelectionColor = Color.Red;
index++;
}
} while (index > -1);
I've been trying to figure out, the best way to tackle this problem.
The problem Im stuck on is where I need to take the user input(word) and put it in the array and try to confirm/validate if all the letters they've use are in the char array(generates 10 random letters)(letterpool) then check again if the word they've use are valid from the dictionary.
I have a dictionary called "dict.txt" which contains 80k words in lowercase
dictionary. i need somehow take the input(uppercase) and be able to locate the word of the dictionary in lowercase
I hope you guys can help me, Programming language Java
Thanks in advance!
Eric
I'd create a HashMap<Character, Integer> and put the random letters in the map.
map.put(letter, 0);
Then I'd go through the letters from your word and do this
Integer value = map.get(letterFromYourWord);
if(value == null){
//raise exception because the letter from your word is not in your random array
} else {
// increment the value from the map
map.put(letterFromYourWord, value++);
}
then go through the map and check if the values are not 0. If there is one with value 0 then your word is not used in your random array.
with this implementation you can extend easily more functionalities, like counting the letters which are used in your word...
For the validWord function I would suggest making use of the binary search for sorted arrays. Something along those lines:
static boolean validWord(String word, final char[] letters)
{
char[] lettersCopy = letters.clone();
Arrays.sort(lettersCopy); // sort so we can use binary search
for(char c : word.toCharArray())
{
if(Arrays.binarySearch(lettersCopy, c) < 0) //char c from word not in letterPool?
{
return false;
}
}
return true;
}
Then in your TRIALS loop you would just call it like this:
if (validWord(input,letterPool))
{
System.out.println("Yes, the letters match");
}else {
System.out.println("No");
}
I am not sure which Dictionary class you are using there so I cannot help you with that.
Btw:
Arctigors answer using hashmaps is more cpu performant yet more heavy on the memory side. (O(n) instead of O(n*lb(m)))