当前位置:首页 » 编程软件 » 混合编译原理

混合编译原理

发布时间: 2023-09-14 02:18:51

‘壹’ 语音编码的编码的分类

语音编码就是对模拟的语音信号进行编码,将模拟信号转化成数字信号,从而降低传输码率并进行数字传输,语音编码的基本方法可分为波形编码、参量编码(音源编码)和混合编码,波形编码是将时域的模拟话音的波形信号经过取样、量化、编码而形成的数字话音信号,参量编码是基于人类语言的发音机理,找出表征语音的特征参量,对特征参量进行编码,混合编译码是结合波形编译码和参量编译码之间的优点。波形编译码器虽然可提供高话音的质量,但数据率低于16kb/s的情况下,在技术上还没有解决音质的问题。 基本原理是在时间轴上对模拟话音信号按照一定的速率来抽样,然后将幅度样本分层量化,并使用代码来表示。在接收端将收到的数字序列经过解码恢复到原模拟信号,保持原始语音的波形形状。话音质量高,编码速率高。如PCM编码类(a率或u率PCM、ADPCM、ADM),编码速率为64-16kb/s,语音质量好。
波形编码的目的在于尽可能精确地再现原来的语音波形,并以波形的保真度即自然度为其质量的主要度量指标,但波形编码所需的码速率较高。 根据语音信号产生的数学模型,通过对语音信号特征参数的提取后进行编码(将特征参数变换成数字代码进行传输)。在接收端将特征参数,结合数学模型,恢复语音,力图使重建语音保持尽可能高的可懂度,重建语音信号的波形同原始语音信号的波形可能会有相当大的区别。如线性预测(LPC)编码类。编码速率低,2.4-1.2kb/s,自然度低,对环境噪声敏感。
这种语音编码的主要质量指标是可懂度,参量编码可以将语音编码以后的速率压得很低。 将波形编码与参数编码相结合,在2.4-1.2kb/s速率上能够得到高质量的合成语音。混合编码把波形编码的高质量和参量编码的高效性融为一体,在参量编码的基础上附加一定的波形编码特征,实现在可懂度的基础上适当地改善自然度的目的。
用于移动通信中的语音编码一般都是混合编码。选择混合编码时,要使比特率、质量、复杂度和处理时延这4个参量及其关系达到综合最佳化。 语音中最基本的元素是音素,大约有128~256个,如果按通常的说话速度,每秒平均发出10个音素,则信息率为:I=[log2(256)10]bps=80bps
把发音看成是以语音速率来传送,则语音编码的极限速率为80bps,从数字化标准的编码速率64kbps,到极限速率80bps,之间的距离,对于理论研究和实践有着极大的吸引力。

‘贰’ 求C++程序设计:四则混合运算表达式的解析与计算

double PostCalculate::calculate(std::string *p,int size)
{
std::stack<string> a;
std::string postExp[20];
int count=0; //对 后缀表达式 计数
for(int i=0;i<size;i++)
{
if(!isSign(p)) //若不是符号 ,即为数字
{
postExp[count]=*p; //将数字直接放入后缀表达式
count++;
}

else if(*p=="+" ||*p=="-")
{
while(!a.empty() && a.top()!="(") //弹出栈中元素直到 栈空 或者 左括号
{
postExp[count]=a.top();
count++;
a.pop();
}
a.push(*p); //将当前元素压栈
}
else if(*p=="*" || *p=="/")
{
while(!a.empty() && a.top()!="(" && a.top()!="+" && a.top()!="-")
{
postExp[count]=a.top();
count++;
a.pop();
}
a.push(*p);
}
else if(*p=="(")
{
a.push(*p);
}
else if(*p==")")
{
while(!a.empty() && a.top()!="(")
{
postExp[count]=a.top();
count++;
a.pop();
}
if(!a.empty() && a.top()=="(")
a.pop();
}
p++;
}
while(!a.empty())
{
postExp[count++]=a.top();
a.pop();
}
double result=postCal(postExp,count);
return result;
}
std::string PostCalculate::dispose(std::string first, std::string second, std::string op)
{
stringstream t;
double r;
double a=stringToDouble(first);
double b=stringToDouble(second);
if(op=="+")
r=a+b;
else if(op=="-")
r=a-b;
else if(op=="*")
r=a*b;
else if(op=="/")
r=a/b;
t<<r;
return t.str();
}
double PostCalculate::postCal(std::string *p,int size)
{
std::stack<string> res;
for(int i=0;i<size;i++)
{
if(!isSign(p)) //遇到数字 压栈
res.push(*p);
else //遇到符号
{
string f=res.top(); //取第2操作数
res.pop();
string s=res.top();//取第1操作数
string r=dispose(s,f,*p);
res.push(r);
}
p++;
}

return stringToDouble(res.top());
}
inline bool PostCalculate::isSign(std::string* s)
{
return (*s=="+"|| *s=="-"|| *s=="*"|| *s=="/"|| *s=="("|| *s==")");
}
inline double PostCalculate::stringToDouble(std::string c) //通过流 实现转换 String -> Double
{
double temp;
stringstream a;
a.str(c);
a>>temp;
return temp;
}

入口函数是pCal.calculate(expression,num)//参数1 是string数组,参数2是数组实际个数,程序里设计是字符数不超过20个,想修改可以在PostCalculate::calculate函数的第4行修改

‘叁’ 怎么实现c语言与汇编语言的混合编程

这个问题有很多做法。如果你的汇编语句比较简单可以采用楼上的做法。
如果的你的汇编比较大,可以写成另外一个汇编文件*.asm。然后根据你的编译器给你的指令,把你的汇编函数抽象出C语言声明。做成*.h文件,供其他人调用。这是现在比较流行的底层API开发模式。
如 我把需要用汇编语句写的功能写一个汇编文件 asm_main.asm,我在该文件的前面 加一句 XDEF asm_main(这是我的编译器的规定,用XDEF),然后在asm_main.h里声明(就是典型的C声明 如 U16 asm_main())。这样你在你的C程序中如果用到汇编功能,只要#include "asm_main.h" 就可以调用用汇编写的函数了。对于大规模的软件开发,这是个很重要的方法。它提供了二次接口供上层调用。你可以把所有硬件驱动或底层API都写成这样子。C语言开发者就不需要了解底层硬件细节了。而且底层汇编的改动也不会影响C。这样你开发的C程序可移植性就高了。当然,你还需要些编译原理的知识。如,在汇编里,asm_main函数只是个标号,写成asm_main: 对吧,但是如果你需要些入口参数怎么办?比如你要抽象出U16 asm_main(char ,char *),这个时候你要考虑参数是怎样入栈的,一般是从右到左依次压栈的,等等还有些问题。
现在的大学本科教育只教一些单片机开发的小技能,没有一个系统的概念。我很愿意把我工作中得来的经验与大家分享。

‘肆’ 编译原理的相关程序

解释程序(interpreter):解释程序是如同编译器的一种语言翻译程序。它与编译器的不同之处在于:它立即执行源程序而不是生成在翻译完成之后才执行的目标代码。从原理上讲,任何程序设计语言都可被解释或被编译,但是根据所使用的语言和翻译情况,很可能会选用解释程序而不用编译器。例如, 我们经常解释BASIC语言而不是去编译它。类似地,诸如LISP 的函数语言也常常是被解释的。
解释程序也经常用于教育和软件的开发,此处的程序很有可能被翻译若干次。而另一方面,当执行的速度是最为重要的因素时就使用编译器,这是因为被编译的目标代码比被解释的源代码要快得多,有时要快10倍或更多。但是,解释程序具有许多与编译器共享的操作,而两者之间也有一些混合之处。 代码生成(code generator):代码生成器得到中间代码(IR),并生成目标机器的代码。正是在编译的这个阶段中,目标机器的特性成为了主要因素。当它存在于目标机器时,使用指令不仅是必须的而且数据的形式表示也起着重要的作用。例如,整型数据类型的变量和浮点数据类型的变量在存储器中所占的字节数或字数也很重要。在上面的示例中,现在必须决定怎样存储整型数来为数组索引生成代码。例如,下面是所给表达式的一个可能的样本代码序列(在假设的汇编语言中):
M O V R0,index ;;
value of index -> R0 M U L R0,2 ;;
double value in R0 M O V R1,&a ;;
address of a -> R1 A D D R1,R0 ;;
add R0 to R1 M O V *R1,6 ;;
constant 6 -> address in R1
在以上代码中,为编址模式使用了一个类似C的协定,因此& a是a的地址(也就是数组的基地址),* R1则意味着间接寄存器地址(因此最后一条指令将值6存放在R1包含的地址中)。这个代码还假设机器执行字节编址,并且整型数占据存储器的两个字节(所以在第2条指令中用2作为乘数)。 目标代码(target code optimizer ):在这个阶段中,编译器尝试着改进由代码生成器生成的目标代码。这种改进包括选择编址模式以提高性能、将速度慢的指令更换成速度快的,以及删除多余的操作。在上面给出的样本目标代码中,还可以做许多更改:在第2条指令中,利用移位指令替代乘法(通常地,乘法很费时间),还可以使用更有效的编址模式(例如用索引地址来执行数组 存储)。使用了这两种优化后,目标代码就变成:
MOV R0,index ;;
value of index -> R0 SHL R0 ;;
double value in R0 MOV &a[R0],6 ;;
constant 6 -> address a + R0
到这里就是编译原理的简要描述,但还应特别强调编译器在其结构细节上差别很大。

‘伍’ 寻求pascal计算四则混合运算的原理

在编译原理里有讲,利用堆栈.
我来简单的说下.
程序中有2个栈,一个放数值,一个放操作符

A 程序开始后,第一次的操作符和数值先入栈
B 获取下一个操作符NextOP
C 把NextOP和栈顶操作符进行优先级比较

情况1.NextOP优先级比栈顶操作符要高的话,把NextOP压入操作符栈.继续步骤B
情况2.NextOP优先级比栈顶操作符要低的话,用栈顶运行符,数值栈拿顶的2个值做运算,运算结果压入数值栈.重复步骤C 如果操作符栈为空,运算结束,步骤D

D 运算结果在数值栈
回答者: cpplyy - 千总 四级 10-8 09:12
1.分治搜索法 每次找到最后运算的符号,对其左右分别深搜到出结果为止
2.堆栈处理法 分数栈与符号栈 先定义常量数组(判断运算\入栈\错误),然后从左到右依次运算 数进数栈 符号与符号栈内比较运算\入栈\错误操作 运算从数栈里拿数与后面的计算 然后结果入数栈 最后结果在数栈里
回答者: LXYXYNT - 举人 四级 10-8 12:50
堆栈就行了
回答者: sd542927172 - 见习魔法师 二级 10-9 20:09
堆栈

表达式的计算应用相当广泛,比如电力调度系统中的计算遥测、车站票务系统中的票价类型计算公式等。
本文讲述中置表达式转换为后置表达式和后置表达式的求值算法,并给出实现的C++源代码,同时给出一个相当简洁的堆栈C++模板类。

中缀表达式到后缀表达式的转换
要把表达式从中缀表达式的形式转换成用后缀表示法表示的等价表达式,必须了解操作符的优先级和结合性。优先级或者说操作符的强度决定求值顺序;优先级高的操作符比优先级低的操作符先求值。 如果所有操作符优先级一样,那么求值顺序就取决于它们的结合性。操作符的结合性定义了相同优先级操作符组合的顺序(从右至左或从左至右)。
转换过程包括用下面的算法读入中缀表达式的操作数、操作符和括号:
1. 初始化一个空堆栈,将结果字符串变量置空。
2. 从左到右读入中缀表达式,每次一个字符。
3. 如果字符是操作数,将它添加到结果字符串。
4. 如果字符是个操作符,弹出(pop)操作符,直至遇见开括号(opening parenthesis)、优先级较低的操作符或者同一优先级的右结合符号。把这个操作符压入(push)堆栈。
5. 如果字符是个开括号,把它压入堆栈。
6. 如果字符是个闭括号(closing parenthesis),在遇见开括号前,弹出所有操作符,然后把它们添加到结果字符串。
7. 如果到达输入字符串的末尾,弹出所有操作符并添加到结果字符串。

后缀表达式求值
对后缀表达式求值比直接对中缀表达式求值简单。在后缀表达式中,不需要括号,而且操作符的优先级也不再起作用了。您可以用如下算法对后缀表达式求值:
1. 初始化一个空堆栈
2. 从左到右读入后缀表达式
3. 如果字符是一个操作数,把它压入堆栈。
4. 如果字符是个操作符,弹出两个操作数,执行恰当操作,然后把结果压入堆栈。如果您不能够弹出两个操作数,后缀表达式的语法就不正确。
5. 到后缀表达式末尾,从堆栈中弹出结果。若后缀表达式格式正确,那么堆栈应该为空。

写在这里不方便,讲解的话+Q244957727
给分拉给分啦~
回答者: wind_teller - 魔法师 四级 10-10 21:57
表达式的计算应用相当广泛,比如电力调度系统中的计算遥测、车站票务系统中的票价类型计算公式等。
本文讲述中置表达式转换为后置表达式和后置表达式的求值算法,并给出实现的C++源代码,同时给出一个相当简洁的堆栈C++模板类。

中缀表达式到后缀表达式的转换
要把表达式从中缀表达式的形式转换成用后缀表示法表示的等价表达式,必须了解操作符的优先级和结合性。优先级或者说操作符的强度决定求值顺序;优先级高的操作符比优先级低的操作符先求值。 如果所有操作符优先级一样,那么求值顺序就取决于它们的结合性。操作符的结合性定义了相同优先级操作符组合的顺序(从右至左或从左至右)。
转换过程包括用下面的算法读入中缀表达式的操作数、操作符和括号:
1. 初始化一个空堆栈,将结果字符串变量置空。
2. 从左到右读入中缀表达式,每次一个字符。
3. 如果字符是操作数,将它添加到结果字符串。
4. 如果字符是个操作符,弹出(pop)操作符,直至遇见开括号(opening parenthesis)、优先级较低的操作符或者同一优先级的右结合符号。把这个操作符压入(push)堆栈。
5. 如果字符是个开括号,把它压入堆栈。
6. 如果字符是个闭括号(closing parenthesis),在遇见开括号前,弹出所有操作符,然后把它们添加到结果字符串。
7. 如果到达输入字符串的末尾,弹出所有操作符并添加到结果字符串。

后缀表达式求值
对后缀表达式求值比直接对中缀表达式求值简单。在后缀表达式中,不需要括号,而且操作符的优先级也不再起作用了。您可以用如下算法对后缀表达式求值:
1. 初始化一个空堆栈
2. 从左到右读入后缀表达式
3. 如果字符是一个操作数,把它压入堆栈。
4. 如果字符是个操作符,弹出两个操作数,执行恰当操作,然后把结果压入堆栈。如果您不能够弹出两个操作数,后缀表达式的语法就不正确。
5. 到后缀表达式末尾,从堆栈中弹出结果。若后缀表达式格式正确,那么堆栈应该为空
在编译原理里有讲,利用堆栈.
我来简单的说下.
程序中有2个栈,一个放数值,一个放操作符

A 程序开始后,第一次的操作符和数值先入栈
B 获取下一个操作符NextOP
C 把NextOP和栈顶操作符进行优先级比较

情况1.NextOP优先级比栈顶操作符要高的话,把NextOP压入操作符栈.继续步骤B
情况2.NextOP优先级比栈顶操作符要低的话,用栈顶运行符,数值栈拿顶的2个值做运算,运算结果压入数值栈.重复步骤C 如果操作符栈为空,运算结束,步骤D

D 运算结果在数值栈
.分治搜索法 每次找到最后运算的符号,对其左右分别深搜到出结果为止
2.堆栈处理法 分数栈与符号栈 先定义常量数组(判断运算\入栈\错误),然后从左到右依次运算 数进数栈 符号与符号栈内比较运算\入栈\错误操作 运算从数栈里拿数与后面的计算 然后结果入数栈 最后结果在数栈里

热点内容
删除引索的sql语句 发布:2024-11-19 12:39:13 浏览:64
智能车算法 发布:2024-11-19 12:34:49 浏览:777
linuxredis启动脚本 发布:2024-11-19 12:31:35 浏览:955
刀片机电脑系统在服务器端 发布:2024-11-19 12:27:16 浏览:861
设备监控源码 发布:2024-11-19 12:26:21 浏览:922
服务器主板是什么样子 发布:2024-11-19 12:08:19 浏览:889
奥迪配置怎么比较 发布:2024-11-19 12:07:33 浏览:522
连接共享打印机无权限访问权限 发布:2024-11-19 12:04:01 浏览:295
大众速腾车载carplay安卓怎么连接 发布:2024-11-19 11:57:12 浏览:515
电脑软件用户密码是什么 发布:2024-11-19 11:51:25 浏览:914