想了好久的问题

zhang_db 2005-06-25 05:35:06
如何将一个字符串转换成一个数学函数

例如“y=sin(x)”就可以得到函数
y=sin(x)
...全文
418 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
luckydean 2005-09-02
  • 打赏
  • 举报
回复

这不是编译器做的事情吗
VivianSnow 2005-08-18
  • 打赏
  • 举报
回复
字符串处理
liixixi 2005-08-15
  • 打赏
  • 举报
回复
看到了这么个有趣的帖子, 真的是不错的事情。

楼上提到编译原理的朋友们, 是否想到了, 他要调的这个sin函数不是内部函数, 是库函数!

也许从字符串 y = x^2 + 3x + 1 中提取函数出来, 用编译原理的方法可以做到, 但是库函数。。。。 似乎有点难。

python语言里有个函数叫exec, 接受一个字符串, 然后执行, 似乎和这个需求差不多, 但是python是脚本语言, 它是以中间代码解释执行为基础的(也许现在有些优化, 我说的是原理), 而以本地代码构成的exe可以理解为 “本地代码解释执行”, 其实缓冲区溢出攻击就是这个原理, 如果有了这样的认识, 那么就可以在程序中实现一个, 接受机器码字符串, 然后执行之的模块, 实现一个动态代码的功能。

可惜的是, 机器码难于构造, 也难于输入, 所以, 又回到了上边的话题, 需要把C语言代码编译, 构成机器码, 但是, 库函数怎么办呢?

一个简单的办法就是把所有库函数的文件带到程序中, 读取所有库文件的导出函数表, 语法分析后, 形成符号对应关系, 再把需要的函数load进内存, 计算相对偏移, 然后调用, 当然, 复制代码也是一个不错的选择。

可惜上述办法有一个致命的问题, 就是编译器优化的问题, ebp被优化掉, 所有局部变量使用esp寻址, 我对这个优化的具体实现方式不是很清楚, 不过, 从直觉上来讲, 当使用ebp寻址的代码和esp寻址的代码出现在一个局部的函数中的时候, 似乎会出问题。

就算很小心的单独load函数, 把所有自定义代码全部是用函数独立出来, 并定好标准调用格式, 实际操作起来还是会有其他问题, 比如库函数不全是计算用的函数, 如果库函数调了api, 那么你还需要自己判断api是否被导入到exe中, 如果没有, 那。。。。 load系统dll吧, 不然你根本无法确定api的偏移, 于是, 所有系统dll的导出符号表, 你也许要带到程序中。

要吃饭了, 饿得开始胡说八道, 大家全当yy, 不用理我。。
ZTAngel 2005-08-15
  • 打赏
  • 举报
回复
看看先
ffansky 2005-08-15
  • 打赏
  • 举报
回复
你说的就是宏
improgrammer 2005-08-15
  • 打赏
  • 举报
回复
VBA就是一个现成的解决方案。
它是可以被集成到你的应用程序中的。
它与COM环境融为一体。
neulxg 2005-08-15
  • 打赏
  • 举报
回复
弱弱的问一句,那象mathematica软件直接输入一个式子,比如1+1,它就能自动识别是一个加法,输入sin[30]-cos[30]就能知道是三角函数加法,究竟其内核是怎么实现的呢?我觉得这跟楼主提的问题很是相似,这个问题我也想了很久,但是至今没能想出一个万全的方法来,望大家继续讨论,期待有更好的方法出现啊
漂流的代码 2005-08-15
  • 打赏
  • 举报
回复
可以用正规则表达式来实现
(VC++.NET)
#include "stdafx.h"
#include <atlrx.h>

int main(int argc, char* argv[])
{

CAtlRegExp< > re;
REParseError r = re.Parse("{[a-z|A-Z]+}={[a-z|A-Z]+.[a-z|A-Z|0-9]+.}");

CAtlREMatchContext< > mc;

re.Match("y=sin(x)",&mc);
for(int i=0;i<mc.m_uNumGroups;i++)
{
const CAtlREMatchContext< >::RECHAR* szStart = 0;
const CAtlREMatchContext< >::RECHAR* szEnd = 0;
mc.GetMatch(i,&szStart,&szEnd);

ptrdiff_t nLength = szEnd - szStart;
printf("%d: \"%.*s\"\n", i, nLength, szStart);
}

getchar();

return 0;
}

输出结果:
0: "y"
1: "sin(x)"

你如果没有vc++.net可以使用微软发布的GRETA来实现
GuaChon 2005-08-14
  • 打赏
  • 举报
回复
字符串处理。简单。没有更好的方法。
EarthKing 2005-08-12
  • 打赏
  • 举报
回复
做下语法解析啊, 如果函数少的话这个不是很难的..
xiaocai0001 2005-08-08
  • 打赏
  • 举报
回复
jixingzhong(瞌睡虫)的方法并不好
你说如果像这样的串“...acos(0.5)...”,你是调用acos(0.5)好呢,还是调用cos(0.5)?
别想偷懒的办法了!看《编译原理》才是正道!
预编译和宏替换对字符串不起作用的。
我啃 2005-08-08
  • 打赏
  • 举报
回复
这样其实就是算式解析罢了
我啃 2005-08-08
  • 打赏
  • 举报
回复
这样速度慢啊~~~学习学习
nmchunxia_zhang 2005-08-08
  • 打赏
  • 举报
回复
我赞称楼上的转化方法!!!
jixingzhong 2005-08-02
  • 打赏
  • 举报
回复
楼主的问题


可以用这样的办法呀


就是在字符串中寻找子串

符合一定的函数形式

然后提取后面的数字

用数学函数来计算



问题这样就解决了 ...
jeah 2005-07-06
  • 打赏
  • 举报
回复
你的这种需求应该是实现不了,如果可以简化需求,例如:定义一个函数列表,提取出字符串里的关键字然后再调用函数,就像umbrella1984(雨伞(曾国文))说的那样...
zhang_db 2005-07-04
  • 打赏
  • 举报
回复
我说的题目的意思是要从一个字符串里提取出一个函数来的
DD_Kevin 2005-07-04
  • 打赏
  • 举报
回复
看看 学习学习
jsjjms 2005-07-04
  • 打赏
  • 举报
回复
说错了。fn(n)不是计算 非波纳怯 数列的。上面那个函数fb(..)才是。
下面那个宏也是实现一个算法的。

那程序的题目

已知数列:k=1 1 2 3 5 8 13 ...
函数 f(3) = 1x2x3 = 6
f(5) = 3x5x8 = 120
求f(n)
(注:这个题目是人家求助的帖子。)
jsjjms 2005-07-04
  • 打赏
  • 举报
回复
//这是我以前发的一个帖子。
//你的问题是 例如“y=sin(x)”就可以得到函数 y=sin(x)
/*
在这个里面 当程序中遇到fn(n)就自动替换成 非波纳怯 数列计算方法
如后面的 ((n<2)?-1:((n==2)? 2:(fb(n-1)*fb(n)*fb(n+1)))),但使用的
时候因为宏是直接替换,不会考虑优先原则,所以在最外层一般都加一个
括号。
*/

#include<stdio.h>
#include<stdlib.h>
int fb(int idx) {return((idx<3)?1:(fb(idx-1)+fb(idx-2)));}
#define fn(n) ((n<2)?-1:((n==2)? 2:(fb(n-1)*fb(n)*fb(n+1))))

int main(int argc, char* argv[])
{
for(int i=1;i<16;i++)printf("%d:\t%d\n",i,fn(i));
return 0;
}
加载更多回复(9)

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧