PERL5 Chapter Nineth associative arrays/hash tables

Source: Internet
Author: User
Tags scalar


Nineth associative arrays/hash tables

by Flamephoenix

I. Limitations of array variables
Second, the definition
Iii. accessing elements of an associative array
Iv. adding elements
V. Creating an associative array
Vi. copying from an array variable to an associative array
Vii. additions and deletions of elements
Viii. listing the index and value of an array
Nine, loop with associative array
X. Creating data structures with associative arrays
1. (single) linked list
2. Structure
3. Tree

I. Limitations of array variables
In the previously mentioned array variables, the elements can be accessed by subscript. For example, the following statement accesses the third element of the array @array:
$scalar = $array [2];
Although arrays are useful, they have a significant flaw in the difficulty of remembering what elements are stored. If we write a program to calculate the number of occurrences of the first letter of the word in a file, it is difficult to implement it using an array, the program code is as follows:

1: #!/usr/local/bin/perl
2:
3:while ($inputline = <STDIN>) {
4:while ($inputline =~/\b[a-z]\s+/g) {
5: $word = $&;
6: $word =~ s/[;.,:-]$//; # Remove Punctuation
7:for ($count = 1; $count <= @wordlist;
8: $count + +) {
9: $found = 0;
10:if ($wordlist [$count-1] eq $word) {
One: $found = 1;
: $wordcount [$count-1] + = 1;
13:last;
14:}
15:}
16:if ($found = = 0) {
: $oldlength = @wordlist;
: $wordlist [$oldlength] = $word;
: $wordcount [$oldlength] = 1;
20:}
21:}
22:}
23:print ("capitalized words and number of occurrences:\n");
24:for ($count = 1; $count <= @wordlist; $count + +) {
25:print ("$wordlist [$count-1]: $wordcount [$count -1]\n");
26:}

The results of the operation are as follows:

Here are a line of
Input.
This Input contains some capitalized words.
^d
Capitalized words and number of occurrences:
Here:1
Input:2
This:1
Capitalized:1

Each time the program reads a line of text from a standard input file, the loop from line fourth matches the first capitalized word in each line, and every time a loop is found, it is assigned to the simple variable $word. After removing the punctuation in line sixth, check to see if the word has ever occurred, 7~15 in the row in @wordlist to do this check, if an element is equal to $word, the corresponding element in the @wordcount increments by one number. If not, that is, no elements in @wordlist are equal to $word, and 16~20 rows add a new element to @wordlist and @wordcount.
Second, the definition
As you can see, the use of array elements creates some problems. First, which element in the @wordlist corresponds to which word is not obvious; even worse, every time a new word is read, the program must check the entire list to see if it has ever occurred, and when the list becomes larger, it can be a lot of effort.
These problems occur because the array elements are accessed by a digital subscript, and in order to solve such problems, Perl defines another array that can be used to access its elements with any simple variable value, which is called an associative array or hash table.
To differentiate associative array variables from normal array variables, Perl uses% as its first character, and array variables begin with @. As with other variable names, the first character after% must be a letter, and subsequent characters can be letters, numbers, or underscores.
Iii. accessing elements of an associative array
The subscript of an associative array can be any simple/scalar value that starts with a $ sign when a single element is accessed, and the subscript is surrounded by curly braces. For example:

$fruit {"Bananas"}
$number {3.14159}
$integer {-7}

Simple variables can also be used as subscripts, such as:
$fruit {$my _fruit}
Iv. adding elements
The simplest way to create an associative array element is to assign a value, such as a statement $fruit{"bananas"} = 1, assign 1 to an associative array%fruit the element labeled bananas, and if the element does not exist, it is created if the array%fruit has never been used.
This feature makes associative arrays very easy to count. Here we use associative arrays to rewrite the program above, and note that this program simplifies a lot by implementing the same functionality.

1: #!/usr/local/bin/perl
2:
3:while ($inputline =) {
4:while ($inputline =~/\b[a-z]\s+/g) {
5: $word = $&;
6: $word =~ s/[;.,:-]$//; # Remove Punctuation
7: $wordlist {$word} + = 1;
8:}
9:}
10:print ("capitalized words and number of occurrences:\n");
11:foreach $capword (keys (%wordlist)) {
12:print ("$capword: $wordlist {$capword}\n");
:}

The results of the operation are as follows:

Here are a line of Input.
This Input contains some capitalized words.
^d
Capitalized words and number of occurrences:
This:1
Input:2
Here:1
Capitalized:1

As you can see, the program is much simpler, reading the input and storing the number of words from 20 lines to 7 rows.
This program uses associative array%wordlist to track the first letter capitalized words, the subscript is the word itself, the element value is the number of occurrences of the word. Line 11th uses the inline function keys (). This function returns the list of subscripts for the associated array, which is used to loop through the foreach statement.
Note: Associative arrays are always stored randomly, so when you access all of their elements with keys (), there is no guarantee that the elements will appear in any order, especially if they do not appear in the order in which they were created.
To control the order in which associative array elements appear, you can use the sort () function to arrange the keys () return values, such as:

foreach $capword (sort keys (%wordlist)) {
Print ("$capword: $wordlist {$capword}\n");
}

V. Creating an associative array
You can create an associative array with a single assignment statement, such as:
%fruit = ("Apples", "n", "Bananas", 9, "oranges", "none");
The associative array created by this statement contains the following three elements:

  • The element labeled apples, with a value of 9
  • and an element with a value of oranges
  • subscript bananas, with a value of none

     Note: When you assign a value to an associative array by using a list, PERL5 allows you to use "= =" or "," to delimit subscripts and values, with "= =" to be more readable, and the above statement to be equivalent to:
     %fruit = ("Apples" =>17, "Bananas" =>9, "oranges" = "none");
Vi. copying from an array variable to an associative array
     as with a list, you can create an associative array from an array variable, of course, with an even number of elements, such as:
      @fruit = ("Apples", "Bananas", 9, "oranges", "none");
    %fruit = @fruit;
     Conversely, you can assign an associative array to an array variable, such as:
    %fruit = ("Grapes", One, "lemons", and so on);
     @fruit =%fruit;
     Note that the order of elements in this statement is undefined, so the array variable @fruit may be ("grapes", One, "lemons", 27) or ("Lemons", "grapes", 11).
     Associative array variables can be directly assigned values, such as:%fruit2 =%fruit1; You can also assign array variables to simple variables and an associative array variable, such as:
      ($var 1, $var 2,%myarray) = @list;
     This statement assigns the first element of @list to $var1, the second to $var2, and the rest to%myarray.
     Finally, associative arrays can be created by returning values to inline functions or user-defined subroutines in the list, and the following example assigns the return value of the split () function-a list-to an associative array variable.

1: #!/usr/local/bin/perl
2:
3: $inputline = <STDIN>;
4: $inputline =~ s/^\s+|\s+\n$//g;
5:%fruit = Split (/\s+/, $inputline);
6:print ("Number of bananas: $fruit {\" bananas\ "}\n");

The results of the operation are as follows:

oranges 5 Apples 7 Bananas Cherries 6
Number of Bananas:11

Vii. additions and deletions of elements
The addition element has been said to add new elements to the associative array by assigning a value to an element that is not present, such as $fruit{"lime"} = 1; Create a new element labeled lime with a value of 1.
Deleting an element is done with an inline function delete, if you want to delete the above element:
Delete ($fruit {"Lime"});
Attention:

1. Be sure to use the Delete function to delete the elements of the associative array, which is the only way.
2. Be sure not to use inline function push, pop, shift, and splice for associative arrays, because their element positions are random.

Viii. listing the index and value of an array
As mentioned above, the keys () function returns a list of the associated array subscripts, such as:

%fruit = ("Apples", 9,          "Bananas", "          cherries", one); @fruitsubs = keys (%fruits);

Here, @fruitsubs are assigned to the list of apples, bananas, and cherries, and again draw attention that this list is out of order and you can use the sort () function if you want to sort alphabetically.
@fruitindexes = sort keys (%fruits);
This result is ("apples", "bananas", "cherries"). Similarly, the inline function values () returns a list of associative array values, such as:

%fruit = ("Apples", 9,           "Bananas", "           cherries", one); @fruitvalues = values (%fruits);

Here, the @fruitvalues possible result is (9,23.11), the order may be different.
Nine, loop with associative array
A Foreach Loop statement with the keys () function has been shown earlier, which is less efficient because each return of a subscript has to be searched for its value, such as:

foreach $holder (keys (%records)) {
$record = $records {$holder};
}

Perl provides a more efficient way of looping, using inline functions each (), such as:

%records = ("Maris", "Aaron", 755, "Young", 511);
while (($holder, $record) = each (%records)) {
# stuff goes here
}

each () function returns a list of two elements, its first element is subscript, the second element is the corresponding value, and finally an empty list is returned.
Note: Never add or remove elements from each () loop, or you will have unpredictable consequences.
X. Creating data structures with associative arrays
Using associative arrays to simulate multiple data structures that are common in other high-level languages, this section describes how to implement them: linked lists, structures, and trees.
1. (single) linked list
Linked list is a relatively simple data structure, can be stored in a certain order of value. Each element contains two fields, one is a value, one is a reference (or pointer), and a pointer to the next element in the list. A special head pointer points to the first element of the linked list.
In Perl, a linked list is easily implemented with an associative array, because the value of one element can be indexed as the next element. The following example lists the list of words in alphabetical order:

%words = ("Abel", "Baker",           "Baker", "Charlie",          "Charlie", "Delta",          "Delta", ""); $header = "Abel";

In the above example, the simple variable $header contains the first word in the linked list, which is also the subscript for the first element of the associative array, and the value of Baker is the subscript for the next element, and so on.
The value of the last element below the delta is an empty string representing the end of the linked list.
A linked list is useful in situations where the number of data to be processed is unknown or it grows with the program running. The following example outputs a word from a file in alphabetical order by using the list.

1: #!/usr/local/bin/perl
2:
3: # Initialize list to empty
4: $header = "";
5:while ($line = <STDIN>) {
6: # Remove leading and trailing spaces
7: $line =~ s/^\s+|\s+$//g;
8: @words = Split (/\s+/, $line);
9:foreach $word (@words) {
Ten: # Remove closing punctuation, if any
One: $word =~ s/[.,;:-]$//;
#: Convert all words to lower case
: $word =~ tr/a-z/a-z/;
: &add_word_to_list ($word);
15:}
16:}
: &print_list;
18:
19:sub Add_word_to_list {
20:local ($word) = @_;
21:local ($pointer);
22:
#: # If List is empty, add first item
24:if ($header eq "") {
: $header = $word;
: $wordlist {$word} = "";
27:return;
28:}
#: # If Word identical to first element in list,
: # do nothing
31:return if ($header eq $word);
: # See whether Word should is the new
A: # First word in the list
34:if ($header gt $word) {
: $wordlist {$word} = $header;
*: $header = $word;
37:return;
38:}
In: # Find place where Word belongs
Max: $pointer = $header;
41:while ($wordlist {$pointer} ne "" &&
: $wordlist {$pointer} lt $word) {
: $pointer = $wordlist {$pointer};
44:}
I: # If Word already seen, do nothing
46:return if ($word eq $wordlist {$pointer});
A: $wordlist {$word} = $wordlist {$pointer};
: $wordlist {$pointer} = $word;
49:}
50:
51:sub Print_list {
52:local ($pointer);
53:print ("Words in this file:\n");
Wu: $pointer = $header;
55:while ($pointer ne "") {
56:print ("$pointer \ n");
£ º $pointer = $wordlist {$pointer};
58:}
59:}

The results of the operation are as follows:

Here is
some words.
Here is more words.
Here is still more words.
^d
Words in this file:
Is
Here
More
Some
Still
Words

This program is divided into three parts:

  • Main program: Read the input and convert to the appropriate format.
  • Subroutine: add_word_to_list, establish sort word list.
  • Sub-Program: print_list, Output word list

The 3rd to 17th line is the main program, the 4th line initializes the linked list, the table header variable $header is set to an empty string, the loop of the 5th line reads one line at a time, the 7th row removes the head, the trailing space, and the 8th line divides the sentence into words. The inner loop of the 9~15 line processes one word at a time, and if the last character of the word is a punctuation mark, it is removed. Line 13th converts the word into a lowercase form, and the 14th line is passed to the subroutine Add_word_to_list.
The subroutine Add_word_to_list first checks if the list is empty at line 24th. If so, the 25th line assigns the word to the $header,26 row to create the first element of the linked list, stored in the associative array%wordlist. If the list is not empty, 37 rows Check whether the first element is the same as the word, and if so, returns immediately. The next step is to check whether the new word should be the first element in the list, that is, its alphabetical order precedes $header. If this is the case, then:
1, create a new element, subscript the new word, its value is the original first word.
2. The new word is assigned to $header.
If the new word should not be the first element, the 40~44 line uses the local variable $pointer to find its appropriate valid position, 41~44 the row to $wordlist{$pointer} is greater than or equal to $word. The next 46 lines see if the word is already in the list, and if it returns, 47~48 will add it to the list. The first 47 lines create a new element $wordlist{$word} with a value of $wordlist{$pointer}, at which point $wordlist{$word} and $wordlist{$pointer} points to the same word. Then, 48 will assign the value of $wordlist{$pointer} to $word, and the $wordlist{$pointer} points to the new element you just created $wordlist{$word}.
Finally, when the processing is finished, the subroutine Print_list () sequentially outputs the linked list, the local variable $pointer contains the value being output, $wordlist {$pointer} is the next value to be output.
Note: It is generally not necessary to use a linked list for these tasks, and it is sufficient to loop in the associative array with sort () and keys (), such as:

foreach $word (sort keys (%wordlist)) {
# Print the sorted list, or whatever}

However, the concept of pointers involved here is very meaningful in other data structures.
2. Structure
Many programming languages can define a structure (structure), a set of data. Each element in the structure has its own name and is accessed by that name.
Perl does not directly provide the structure of this data structure, but can be modeled with associative arrays. For example, simulate the following structure in the C language:

struce{
int field1;
int field2;
int field3; }mystructvar;

What we're going to do is define an associative array of three elements, labeled Field1, Field2, field3, for example:

%mystructvar = ("Field1", "",
"Field2", "",
"Field3", "", ");

Like the definition of the C language above, this associative array%mystrctvar has three elements, the subscripts are field1, Field2, field3, and the initial values of each element are empty strings. The access and assignment of each element is done by specifying a subscript, such as:
$mystructvar {"Field1"} = 17;
3. Tree
Another data structure that is often used is the tree. A tree is similar to a linked list, but each node points to more than one element. The simplest tree is a two-fork tree, each node pointing to another two elements, called the left Dial hand node and the right child node (or child), each child node pointing to two grandchild nodes, and so on.
Note: The tree described here is one-way from the list above, each node points to its child nodes, but the child nodes do not point to the parent node.
The concept of a tree can be described as follows:

  • Because each child node is a tree, the left/right child node is also referred to as the left/right subtree. (sometimes called Left/right branch)
  • The first node (a node that is not a child node of any node) is called the root of the tree.
  • A node without children (child nodes) is called a leaf node.

There are a number of ways to implement tree structure using associative arrays, and the best one should be to add left and right to the child nodes to access them. For example, Alphaleft and Alpharight point to the left and right child nodes of Alpha. The following is a routine that creates a two-tree and traverses it using this method:

1: #!/usr/local/bin/perl
2:
3: $rootname = "parent";
4:%tree = ("Parentleft", "Child1",
5: "Parentright", "Child2",
6: "Child1left", "Grandchild1",
7: "Child1right", "Grandchild2",
8: "Child2left", "grandchild3",
9: "Child2right", "grandchild4");
#: # Traverse Tree, printing its elements
One: &print_tree ($rootname);
12:
13:sub Print_tree {
14:local ($nodename) = @_;
15:local ($leftchildname, $rightchildname);
16:
: $leftchildname = $nodename. "Left";
: $rightchildname = $nodename. "Right";
19:if ($tree {$leftchildname} ne "") {
: &print_tree ($tree {$leftchildname});
21:}
22:print ("$nodename \ n");
23:if ($tree {$rightchildname} ne "") {
: &print_tree ($tree {$rightchildname});
25:}
26:}

The resulting output is as follows:

Grandchild1
Child1
Grandchild2
Parent
Grandchild3
Child2
Grandchild4

The program creates a two-fork tree such as:

Note that the function print_tree () outputs the names of each node in the order "Zuozi, node, right subtree", which is called "left-order traversal". If the 22nd line is moved to 19 lines before the output node point, and then output Zuozi, right subtree, then the "Middle sequence traversal", if the 22nd row is moved to 25 rows, the output order is Zuozi, right subtree, node, then "right sequence traversal".
You can create other data structures, such as databases, by using the same method, that is, the connection string, which makes up the subscript.

Previous chapter Next Chapter catalogue

PERL5 Chapter Nineth associative arrays/hash tables

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.