Лекция
Привет, сегодня поговорим про problem a bibtex and solve by c++ && php, обещаю рассказать все что знаю. Для того чтобы лучше понимать что такое problem a bibtex and solve by c++ && php , настоятельно рекомендую прочитать все из категории Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend) .
Problem A. BibTEX
Input file: bibtex.in
Output file: bibtex.out
Time limit: 1 second
Memory limit: 256 megabytes
BibTeX is a tool for formatting lists of references. The BibTeX tool is typically used together with the
LaTeX document preparation system. BibTeX uses a style-independent text-based file format for lists of
bibliography items, such as articles, books, theses.
In this problem you will have to emulate the part of BibTeX to create bibliography based on book and
article references description.
Reference description starts with “@reference type” followed by ‘{’ followed by a list of fields formatted
as “name = "value"”, separated by commas, followed by ‘}’.
Your program must support the following reference types:
• article — An article from a journal or magazine.
Required fields: author, title, journal, year
Optional fields: volume, number, pages
• book — A book with an explicit publisher.
Required fields: author, title, publisher, year
Optional fields: volume
The fields are formatted as follows:
Field Description
author Each author is formatted as “Name1 Name2 ... Surname”. There are
at least 1 and at most 10 names. If there are several authors, they are
separated by “and”. No author has name or surname equal to “and”.
The total length of the field doesn’t exceed 200 characters. Names and
surnames contain only letters of the English alphabet and are separated
by a space.
title Title of the source. A string of up to 200 characters containing letters
of the English alphabet, spaces, digits and punctuation.
journal, publisher Journal name or publisher name. A string of up to 200 characters containing
letters of the English alphabet, spaces, digits and punctuation.
year Integer number from 1500 to 2008.
volume Integer number from 1 to 106.
number Integer number from 1 to 106.
pages Formatted as “from--to” or as “page”. “From”, “to” and “page” are
integers from 1 to 106, “from” < “to”.
Authors of each source are sorted by surname, then by first name, second name, etc. After that all
references are sorted by first author surname, then first author first name, then first author second name,
etc, then by second author surname, etc, (if corresponding name doesn’t exist, empty string is used
instead) then by title. No two references have the same set of authors and the same title (except books
that can have several volumes, such references are sorted by the volume).
Each article reference is formatted as:
“Authors Title // Journal[, Volume][ (Number)] -- year[ -- pages]”.
Page 1 of 12
Andrew Stankevich Contest 30
Petrozavodsk, Thursday, February 7, 2008
Here “[...]” means optional part. Authors are separated by comma. Each author is formatted as
“Surname I1. I2. ...” where I1, I2, etc are author’s initials (the first letter of the author’s corresponding
name). Pages are formatted either as “p. page” if there is only one page, or “pp. from--to”
if there are many.
Each book reference is formatted as:
“Authors Title[, Vol. Volume] -- Publisher, Year”.
All references are numbered starting from 1 and preceded by their number in square brackets.
See example for further reference.
Input
Input file contains BibTeX reference list containing up to 100 references. All entries in the input file are
case sensitive. All elements of input file are separated by at least one space and/or line feed.
Output
Output the bibliography in the required format.
Example
bibtex.in
@book
{
author = "Donald Ervin Knuth",
title = "The Art of Computer Programming",
volume = "1",
publisher = "Addison-Wesley Professional",
year = "1997"
}
@book
{
author = "Donald Ervin Knuth",
title = "The Art of Computer Programming",
volume = "2",
publisher = "Addison-Wesley Professional",
year = "1997"
}
@article
{
author = "Robert Endre Tarjan and Andrew Goldberg",
title = "A new approach to the maximum flow problem",
journal = "Journal ACM",
volume = "35",
year = "1988",
pages = "921--940"
}
bibtex.out
[1] Goldberg A., Tarjan R. E. A new approach to the maximum flow problem // Journal ACM, 35 -- 1988 -- pp. 921--940
[2] Knuth D. E. The Art of Computer Programming, Vol. 1 -- Addison-Wesley Professional, 1997
[3] Knuth D. E. The Art of Computer Programming, Vol. 2 -- Addison-Wesley Professional, 1997
#include <cstdio> | |
#include <algorithm> | |
#include <cstring> | |
#include <iostream> | |
#include <string> | |
#include <vector> | |
#include <cctype> | |
#include <sstream> | |
#define SIZE(x) ((int)(x).size()) | |
#define ALL(x) (x).begin(), (x).end() | |
#define Vector std::vector | |
#define String std::string | |
const int MAX_NAME = 10; | |
struct Author { //{{{ | |
String surname, name[MAX_NAME]; | |
void clear() { | |
surname = ""; | |
for (int i = 0; i < MAX_NAME; i++) { | |
name[i] = ""; | |
} | |
} | |
Author() { | |
clear(); | |
} | |
bool operator !=(const Author& o) const { | |
if (surname != o.surname) { | |
return true; | |
} | |
for (int i = 0; i < MAX_NAME; i++) { | |
if (name[i] != o.name[i]) { | |
return true; | |
} | |
} | |
return false; | |
} | |
bool operator <(const Author& o) const { | |
if (surname != o.surname) { | |
return surname < o.surname; | |
} | |
for (int i = 0; i < MAX_NAME; i++) { | |
if (name[i] != o.name[i]) { | |
return name[i] < o.name[i]; | |
} | |
} | |
return false; | |
} | |
void print() { | |
printf("%s", surname.c_str()); | |
for (int i = 0; i < MAX_NAME && SIZE(name[i]) > 0; i++) { | |
putchar(' '); | |
putchar(toupper(name[i][0])); | |
putchar('.'); | |
} | |
} | |
}; //}}} | |
struct Reference { //{{{ | |
bool isarticle; | |
Vector <Author> authors; | |
String title, journal, publisher; | |
int year, volume, number, page[2]; | |
void clear() { | |
isarticle = false; | |
authors.clear(); | |
title = journal = publisher = ""; | |
year = volume = number = page[0] = page[1] = -1; | |
} | |
Reference() { | |
clear(); | |
} | |
void normalize() { | |
std::sort(ALL(authors)); | |
} | |
bool operator <(const Reference& o) const { | |
int max = std::max(SIZE(authors), SIZE(o.authors)); | |
for (int i = 0; i < max; i++) { | |
if (i < SIZE(authors) && i < SIZE(o.authors)) { | |
if (authors[i] != o.authors[i]) { | |
return authors[i] < o.authors[i]; | |
} | |
} else { | |
return i >= SIZE(authors); | |
} | |
} | |
if (title != o.title) { | |
return title < o.title; | |
} | |
return volume < o.volume; | |
} | |
void authors_title_print() { | |
for (int i = 0; i < SIZE(authors); i++) { | |
putchar(' '); | |
authors[i].print(); | |
putchar(i < SIZE(authors) - 1 ? ',' : ' '); | |
} | |
printf("%s", title.c_str()); | |
} | |
void article_print(int id) { | |
printf("[%d]", id); | |
authors_title_print(); | |
printf(" // "); | |
printf("%s", journal.c_str()); | |
if (volume != -1) { | |
printf(", %d", volume); | |
} | |
if (number != -1) { | |
printf(" (%d)", number); | |
} | |
printf(" -- %d", year); | |
if (page[0] != -1) { | |
if (page[0] == page[1]) { | |
printf(" -- p. Об этом говорит сайт https://intellect.icu . %d", page[0]); | |
} else { | |
printf(" -- pp. %d--%d", page[0], page[1]); | |
} | |
} | |
puts(""); | |
} | |
void book_print(int id) { | |
printf("[%d]", id); | |
authors_title_print(); | |
if (volume != -1) { | |
printf(", Vol. %d", volume); | |
} | |
printf(" -- %s, %d\n", publisher.c_str(), year); | |
} | |
}; //}}} | |
Vector <Reference> vector; | |
int n; | |
Author aut; | |
Reference ref; | |
char a[int(1e7) + 10]; | |
char buf[int(1e6) + 10]; | |
int next_space(int p) { | |
for (p++; p < n && a[p] != ' ' && a[p] != '{'; p++); | |
return p; | |
} | |
int next_char(int p) { | |
for (p++; p < n && a[p] == ' '; p++); | |
return p; | |
} | |
int next_break(int p) { | |
for (p++; p < n && a[p] != '{' && a[p] != '}' && a[p] != '='; p++); | |
if (a[p] == '=') { | |
for (; a[p] != ','; p--); | |
} | |
return p; | |
} | |
int next_double(int p) { | |
for (p++; p < n && a[p] != '"'; p++); | |
return p; | |
} | |
int to_number(const String& s) { | |
std::istringstream sin(s); | |
int x; | |
sin >> x; | |
return x; | |
} | |
int main() { | |
n = 0; | |
while (gets(buf)) { | |
int m = strlen(buf); | |
for (int i = 0; i < m; i++) { | |
a[n++] = buf[i]; | |
} | |
} | |
a[n] = 0; | |
for (int i = 0, j; i < n; i++) { | |
if (a[i] != '@') { | |
continue; | |
} | |
ref.clear(); | |
j = next_space(i); | |
if (String(a + i, a + j) == String("@article")) { | |
ref.isarticle = true; | |
} else { | |
ref.isarticle = false; | |
} | |
i = next_break(i); | |
while (true) { | |
j = next_space(i = next_char(i)); | |
String token = String(a + i, a + j); | |
int s = next_double(j); | |
int t = next_break(s); | |
int pos = t; | |
s++; | |
for (; a[t] != '"'; t--); | |
String str(a + s, a + t); | |
if (token == String("author")) { | |
std::istringstream sin(str); | |
String tmp; | |
Vector <String> v; | |
while (sin >> tmp) { | |
v.clear(); | |
do { | |
if (tmp == String("and")) { | |
break; | |
} | |
v.push_back(tmp); | |
} while (sin >> tmp); | |
aut.clear(); | |
aut.surname = v.back(); | |
for (int i = 0; i < SIZE(v) - 1; i++) { | |
aut.name[i] = v[i]; | |
} | |
ref.authors.push_back(aut); | |
} | |
} else { | |
if (token == String("title")) { | |
ref.title = str; | |
} else if (token == String("journal")) { | |
ref.journal = str; | |
} else if (token == String("publisher")) { | |
ref.publisher = str; | |
} else if (token == String("year")) { | |
ref.year = to_number(str); | |
} else if (token == String("volume")) { | |
ref.volume = to_number(str); | |
} else if (token == String("number")) { | |
ref.number = to_number(str); | |
} else if (token == String("pages")) { | |
bool flag = true; | |
for (int p = 0; p < SIZE(str); p++) { | |
if (str[p] == '-') { | |
ref.page[0] = to_number(str.substr(0, p)); | |
ref.page[1] = to_number(str.substr(p + 2, SIZE(str))); | |
flag = false; | |
break; | |
} | |
} | |
if (flag) { | |
ref.page[0] = ref.page[1] = to_number(str); | |
} | |
} | |
} | |
i = pos; | |
if (a[pos] == '}') { | |
break; | |
} | |
} | |
ref.normalize(); | |
vector.push_back(ref); | |
} | |
std::sort(ALL(vector)); | |
for (int i = 0; i < SIZE(vector); i++) { | |
if (vector[i].isarticle) { | |
vector[i].article_print(i + 1); | |
} else { | |
vector[i].book_print(i + 1); | |
} | |
} | |
} |
<?php
class Biblio
{
private $finput = '';
private $foutput = '';
public function __construct($finput = '', $foutput = '')
{
$this->finput = $finput;
$this->foutput = $foutput;
}
private $replace = array(
'author=' => '"author"=>',
'title=' => '"title"=>',
'journal=' => '"journal"=>',
'publisher=' => '"publisher"=>',
'year=' => '"year"=>',
'volume=' => '"volume"=>',
'number=' => '"number"=>',
'pages=' => '"pages"=>',
'author =' => '"author"=>',
'title =' => '"title"=>',
'journal =' => '"journal"=>',
'publisher =' => '"publisher"=>',
'year =' => '"year"=>',
'volume =' => '"volume"=>',
'number =' => '"number"=>',
'pages =' => '"pages"=>',
);
private $data = array();
public function createData()
{
$f = fopen($this->finput, "r");
$arr = array();
$tmp_st = '';
$record = 0;
$type='none';
while (!feof($f)) {
$st = fgets($f);
$st = trim($st);
if ($st[0] == '@') {
$type='none';
if ($st=='@article') $type='article';
if ($st=='@book') $type='book';
}
if ($st[0] == '{' ) {
$tmp_st = '';
}
if ($st[0] != '{' && $st[0] != '}' && $st[0] != '@') {
$tmp_st .= $st;
}
if ($st[0] == '}') {
$tmp_st = preg_replace("/[ ]{2,}/", ' ', $tmp_st);
$tmp_st = strtr($tmp_st, $this->replace);
$tmp_st = '$myarray=array(' . $tmp_st . ');';
eval($tmp_st);
if (isset($myarray['author'])) {
$myarray['author'] = $this->authorFormated($myarray['author']);
}
$myarray['type']=$type;
$arr[] = $myarray;
$record++;
}
}
fclose($f);
$this->data = $arr;
return $this;
}
private function cmp($a, $b)
{
return strcasecmp($a["author"], $b["author"]);
}
private function authorFormated($st)
{
$res =array();
$resst='';
$st = explode(' and', $st);
foreach ($st as $numAutor => $onepeople)
{
$onepeople = trim($onepeople);
$ar = explode(' ', $onepeople);
$cnt = count($ar);
if ($cnt == 2) $res[]=array('surname'=>array_pop($ar),'name'=> $ar[0]{0} );
if ($cnt == 3) $res[]=array('surname'=>array_pop($ar),'name'=> $ar[0]{0},'patronymic'=>$ar[1]{0}) ;
}
usort($res, array('Biblio','cmp'));
$cntres = count($res);
foreach ($res as $num=>$onepeople) {
if (isset($onepeople['patronymic']))
$resst.=$onepeople['surname'].' '.$onepeople['name'].'. '.$onepeople['patronymic'].'.';
else $resst.=$onepeople['surname'].' '.$onepeople['name'].'.';
if ($num<$cntres-1) $resst.=', ';
}
return $resst;
}
private function cmp2($a, $b)
{
$c= strcasecmp($a["author"], $b["author"]);
if (($c==0 ) && isset($a["volume"])&& isset($b["volume"]) )
$c=((int)$a["volume"]<(int)$b["volume"])?-1:1;
return $c ;
}
public function dataSort()
{
$data = $this->data;
usort($data, array('Biblio','cmp2'));
$this->data=$data;
return $this;
}
public function saveData()
{
$data = $this->data;
$fp = fopen($this->foutput, "w");
foreach ($data AS $i=>$one){
$st='';
if ($one['type']=='article') $st='['.($i+1).'] '.$one['author'].' '.$one["title"].
' // '.$one["journal"].
(( isset($one["volume"]) &&$one["volume"]!='')?', '.$one["volume"]:' ' ).
(( isset($one["number"]) &&$one["number"]!='')?' ('.$one["number"].') ':'' ).
' -- '.$one["year"].
(( isset($one["pages"]) &&$one["pages"]!='')?' -- pp. '.$one["pages"]:' ' );
if ($one['type']=='book') $st='['.($i+1).'] '.$one['author'].' '.$one["title"].
(( isset($one["volume"]) &&$one["volume"]!='')?', Vol. '.$one["volume"]:' ' ).' -- '.$one["publisher"].', '.$one["year"];
fwrite($fp, $st.PHP_EOL);
}
fclose($fp);
return 1;
}
}
// type==article “Authors Title // Journal[, Volume][ (Number)] -- year[ -- pages]”.
// type==book “Authors Title[, Vol. Volume] -- Publisher, Year”.
$bi = new Biblio('bibtex.in', 'bibtex.out');
$bi->createData()->dataSort()->saveData();
?>
use function eval(), usort(). acess to char of string by type {i}
see solve in attach file this mail
need correct format date in input file bibtex.in
need valid permission on create file bibtex.out
Надеюсь, эта статья про problem a bibtex and solve by c++ && php, была вам полезна, счастья и удачи в ваших начинаниях! Надеюсь, что теперь ты понял что такое problem a bibtex and solve by c++ && php и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)
Комментарии
Оставить комментарий
Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)
Термины: Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)